mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 22:31:06 +08:00
docs: troubleshooting tips for cross-account admin perms and "Microsoft Edge can't read or write to its data directory" error (#2931)
Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
This commit is contained in:
parent
4257decf30
commit
79db5a4657
@ -203,6 +203,153 @@ you can make the webview background transparent using the following config:
|
||||
})
|
||||
```
|
||||
|
||||
## 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
|
||||
@ -213,3 +360,4 @@ 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).
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user