# 故障排除

各种故障排除技巧。

## `wails` 命令好像不见了？

如果您的系统报告缺少 `wails` 命令，请确保您已正确遵循 Go 安装指南。 通常，这意味着您的用户 home 目录中的 `go/bin` 目录不在 `PATH` 环境变量中。 通常情况下还需要关闭并重新打开任何已打开的命令提示符，以便安装程序对环境所做的更改反映在命令提示符中。

## 我的应用程序正在显示白屏/空白屏幕

检查您的应用程序是否包含正确目录中的资产。 在您的 `main.go` 文件中，您将拥有类似于以下代码的内容：

```go
//go:embed all:frontend/dist
var assets embed.FS
```

检查它是否 `frontend/dist` 包含您的应用程序资产。

### Mac

如果在 Mac 上发生这种情况，请尝试将以下内容添加到您的 `Info.plist`:

```xml
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>
```

参考：https://github.com/wailsapp/wails/issues/1504#issuecomment-1174317433

## Mac 应用程序无效

如果您构建的应用程序在 finder 中如下所示：

```mdx-code-block
<p className="text--center">
  <img
    src={
      require("@site/static/img/troubleshooting/invalid_mac_app.png").default
    }
  />
</p>
```

您的申请很可能 `info.plist` 是无效的。 更新 `build/<yourapp>.app/Contents/info.plist`文件 并检查数据是否有效，比如：检查二进制名称是否正确。 要保留更改，请将文件复制回 `build/darwin` 目录。

## 我的应用程序未在 Windows 资源管理器中显示正确的图标

如果您的应用程序未显示正确的图标，请尝试删除位于 `C:\Users\<您的用户名>\AppData\Local` 目录中的隐藏 `IconCache.db` 文件。 这将强制 Windows 重建图标缓存。

来源：https://github.com/wailsapp/wails/issues/2360#issuecomment-1556070036

## 无法使用可变参数

如果您有使用可变参数定义的后端方法，例如：

```go
func (a *App) TestFunc(msg string, args ...interface{}) error {
    // Code
}
```

像这样从前端调用此方法将失败：

```js
var msg = "Hello: ";
var args = ["Go", "JS"];
window.go.main.App.TestFunc(msg, ...args)
  .then((result) => {
    //do things here
  })
  .catch((error) => {
    //handle error
  });
```

解决方法：

```js
var msg = "Hello ";
var args = ["Go", "JS"];
window.go.main.App.TestFunc(msg, args)
  .then((result) => {
    //without the 3 dots
    //do things here
  })
  .catch((error) => {
    //handle error
  });
```

致谢：https://github.com/wailsapp/wails/issues/1186

## 我正在尝试安装Wails时获取代理错误

如果您遇到这样的错误：

```
"https://proxy.golang.org/github.com/wailsapp/wails/cmd/wails/@v/list": dial tcp 172.217.163.49:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
```

这可能是因为官方 Go Proxy 被阻止（中国用户报告了这一点）。 解决方案是手动设置代理，例如：

```
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
```

来源：https://github.com/wailsapp/wails/issues/1233

## 没有生成正确的 TypeScript 类型

有时生成的 TypeScript 没有正确的类型。 `ts_type` 为了缓解这种情况，可以使用 struct 标签指定应该生成哪些类型。 有关详细信息，请阅读 [此](https://github.com/tkrajina/typescriptify-golang-structs#custom-types) 内容。

## 当我离开 `index.html`时，我无法在前端调用方法

如果您导航 `index.html` 到一个新的 html 文件，上下文将会丢失。 这可以通过将以下导入添加到 `<head>` 您导航到的任何新页面的部分来解决：

```html
<head>
  <script src="/wails/ipc.js"></script>
  <script src="/wails/runtime.js"></script>
</head>
```

来源：https://github.com/wailsapp/wails/discussions/1512

## 运行 `wails dev` 出现 `too many open files` 错误

默认情况下，macOS 最多只能打开 256 个文件。 这会影响 `wails dev` 命令 可以通过在终端中运行：`ulimit -n 1024` 来增加此限制。

FSNotify 正在 [寻求转移到苹果](https://github.com/fsnotify/fsnotify/issues/11)。 如果这不能很快完成，我们将创建自己的实现，在 [此处](https://github.com/wailsapp/wails/issues/1733) 跟踪。

## 我的 Mac 应用程序给了我奇怪的编译错误

一些用户报告看到编译错误，如下所示：

```shell
# github.com/wailsapp/wails/v2/internal/frontend/desktop/darwin
In file included from ../../pkg/mod/github.com/wailsapp/wails/v2@v2.0.0-beta.44.2/internal/frontend/desktop/darwin/callbacks.go:9:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:12:
/Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSBundle.h:91:143: error: function does not return NSString
- (NSAttributedString *)localizedAttributedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName NS_FORMAT_ARGUMENT(1) NS_REFINED_FOR_SWIFT API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0));
                                                         ~~~~~~~~~~~~~~                                                                       ^                  ~
/Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:103:48: note: expanded from macro 'NS_FORMAT_ARGUMENT'
        #define NS_FORMAT_ARGUMENT(A) __attribute__ ((format_arg(A)))
```

这 _通常_ 是由于您正在运行的操作系统版本和安装的 XCode 命令行工具的版本不匹配。 如果您看到这样的错误，请尝试将您的 XCode 命令行工具升级到最新版本。

如果重新安装 Xcode 命令工具仍然失败，您可以通过以下方式检查工具包所在的路径：

`xcode-select -p`

如果显示 `/Applications/Xcode.app/Contents/Developer` ，运行 `sudo xcode-select --twitter /Library/Developer/CommandLineTools`

来源：https://github.com/wailsapp/wails/issues/1806 和 https://github.com/wailsapp/wails/issues/1140#issuecomment-1290446496

## My application won't compile on Mac

如果您遇到这样的错误：

```shell
l1@m2 GoEasyDesigner % go build -tags dev -gcflags "all=-N -l"
/Users/l1/sdk/go1.20.5/pkg/tool/darwin_arm64/link: running clang failed: exit status 1
Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_UTType", referenced from:
      objc-class-ref in 000016.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
Ensure you have the latest SDK installed. If so and you're still experiencing this issue, try the following:

```shell
export CGO_LDFLAGS="-framework UniformTypeIdentifiers" && go build -tags dev -gcflags "all=-N -l"
```

Sources: https://github.com/wailsapp/wails/pull/2925#issuecomment-1726828562


--

## 无法启动服务：主机版本“x.x.x”与二进制版本“x.x.x”不匹配

最好将 `frontend/node_modules` 和 `frontend/package-lock.json` 添加到您的 `.gitignore` 中。 否则，当在另一台可能安装了不同版本 Node 的机器上打开您的存储库时，您可能无法运行您的应用程序。

如果发生这种情况，只需删除 `frontend/node_modules` 和 `frontend/package-lock.json` 并再次运行 `wails build` 或 `wails dev` 命令。

## 构建过程停留在“生成绑定”

绑定生成过程在特殊模式下运行应用程序。 如果应用程序有意或无意地包含一个无限循环(即在 `wails.Run()` 结束后不退出)，这可能导致构建过程停留在绑定生成阶段。 请确保您的代码正确退出。

## Mac application flashes white at startup

This is due to the default background of the webview being white. If you want to use the window background colour instead, you can make the webview background transparent using the following config:

```go
    err := wails.Run(&options.App{
        Title:  "macflash",
        Width:  1024,
        Height: 768,
        // Other settings
        Mac: &mac.Options{
            WebviewIsTransparent: true,
        },
    })
```

## I get a "Microsoft Edge can't read or write to its data directory" error when running my program as admin on Windows

You set your program to require admin permissions and it worked great! Unfortunately, some users are seeing a "Microsoft Edge can't read or write to its data directory" error when running it.

When a Windows machine has two local accounts:

- Alice, an admin
- Bob, a regular user

Bob sees a UAC prompt when running your program. Bob enters Alice's admin credentials into this prompt. The app launches with admin permissions under Alice's account.

Wails instructs WebView2 to store user data at the specified `WebviewUserDataPath`. It defaults to `%APPDATA%\[BinaryName.exe]`.

Because the application is running under Alice's account, `%APPDATA%\[BinaryName.exe]` resolves to `C:\Users\Alice\AppData\Roaming\[BinaryName.exe]`.

WebView2 [creates some child processes under Bob's logged-in account instead of Alice's admin account](https://github.com/MicrosoftEdge/WebView2Feedback/issues/932#issue-807464179). Since Bob cannot access `C:\Users\Alice\AppData\Roaming\[BinaryName.exe]`, the "Microsoft Edge can't read or write to its data directory" error is shown.

Possible solution #1:

Refactor your application to work without constant admin permissions. If you just need to perform a small set of admin tasks (such as running an updater), you can run your application with the minimum permissions and then use the `runas` command to run these tasks with admin permissions as needed:

```go
//go:build windows

package sample

import (
    "golang.org/x/sys/windows"
    "syscall"
)

// Calling RunAs("C:\path\to\my\updater.exe") shows Bob a UAC prompt. Bob enters Alice's admin credentials. The updater launches with admin permissions under Alice's account.
func RunAs(path string) error {
    verbPtr, _ := syscall.UTF16PtrFromString("runas")
    exePtr, _ := syscall.UTF16PtrFromString(path)
    cwdPtr, _ := syscall.UTF16PtrFromString("")
    argPtr, _ := syscall.UTF16PtrFromString("")

    var showCmd int32 = 1 //SW_NORMAL

    err := windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd)
    if err != nil {
        return err
    }
    return nil
}
```

Possible solution #2:

Run your application with extended permissions. If you absolutely must run with constant admin permissions, WebView2 will function correctly if you use a data directory accessible by both users and you also launch your app with the `SeBackupPrivilege`, `SeDebugPrivilege`, and `SeRestorePrivilege` permissions. Here's an example:

```go
package main

import (
    "embed"
    "os"
    "runtime"

    "github.com/fourcorelabs/wintoken"
    "github.com/hectane/go-acl"
    "github.com/wailsapp/wails/v2"
    "github.com/wailsapp/wails/v2/pkg/options"
    "github.com/wailsapp/wails/v2/pkg/options/assetserver"
    "github.com/wailsapp/wails/v2/pkg/options/windows"
)

//go:embed all:frontend/dist
var assets embed.FS

const (
    fixedTokenKey = "SAMPLE_RANDOM_KEY"
    fixedTokenVal = "with-fixed-token"
    webviewDir    = "C:\\ProgramData\\Sample"
)

func runWithFixedToken() {
    println("Re-launching self")
    token, err := wintoken.OpenProcessToken(0, wintoken.TokenPrimary) //pass 0 for own process
    if err != nil {
        panic(err)
    }
    defer token.Close()

    token.EnableTokenPrivileges([]string{
        "SeBackupPrivilege",
        "SeDebugPrivilege",
        "SeRestorePrivilege",
    })

    cmd := exec.Command(os.Args[0])
    cmd.Args = os.Args
    cmd.Env = os.Environ()
    cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", fixedTokenKey, fixedTokenVal))
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.SysProcAttr = &syscall.SysProcAttr{Token: syscall.Token(token.Token())}
    if err := cmd.Run(); err != nil {
        println("Error after launching self:", err)
        os.Exit(1)
    }
    println("Clean self launch :)")
    os.Exit(0)
}

func main() {
    if runtime.GOOS == "windows" && os.Getenv(fixedTokenKey) != fixedTokenVal {
        runWithFixedToken()
    }

    println("Setting data dir to", webviewDir)
    if err := os.MkdirAll(webviewDir, os.ModePerm); err != nil {
        println("Failed creating dir:", err)
    }
    if err := acl.Chmod(webviewDir, 0777); err != nil {
        println("Failed setting ACL on dir:", err)
    }

    app := NewApp()

    err := wails.Run(&options.App{
        Title:  "sample-data-dir",
        Width:  1024,
        Height: 768,
        AssetServer: &assetserver.Options{
            Assets: assets,
        },
        Bind: []interface{}{
            app,
        },
        Windows: &windows.Options{
            WebviewUserDataPath: webviewDir,
        },
    })

    if err != nil {
        println("Error:", err.Error())
    }
}
```

If you use a data directory accessible by both users but not the extended privileges, you will receive a WebView2 `80010108 The object invoked has disconnected from its clients` error.

Possible future solution #3: [run WebView2 using an in-memory mode if implemented](https://github.com/MicrosoftEdge/WebView2Feedback/issues/3637#issuecomment-1728300982).

## WebView2 installation succeeded, but the wails doctor command shows that it is not installed

If you have installed WebView2, but the `wails doctor` command shows that it is not installed, it is likely that the WebView2 runtime installed was for a different architecture. You can download the correct runtime from [here](https://developer.microsoft.com/en-us/microsoft-edge/webview2/).

Source: https://github.com/wailsapp/wails/issues/2917

## WebVie2wProcess failed with kind

If your Windows app generates this kind of error, you can check out what the error means [here](https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2processfailedkind?view=webview2-winrt-1.0.2045.28).

