diff --git a/v3/UNRELEASED_CHANGELOG.md b/v3/UNRELEASED_CHANGELOG.md index 33638e7fc86..2840c09bebd 100644 --- a/v3/UNRELEASED_CHANGELOG.md +++ b/v3/UNRELEASED_CHANGELOG.md @@ -23,12 +23,14 @@ After processing, the content will be moved to the main changelog and this file ## Fixed +- Fix `go mod vendor` failing with `pattern arm64/WebView2Loader.dll: no matching files found` on every platform, by removing the embeds that referenced binaries never shipped in the module, fixing [#5782](https://github.com/wailsapp/wails/issues/5782) and [#5376](https://github.com/wailsapp/wails/issues/5376), in [PR](https://github.com/wailsapp/wails/pull/6031) by @Grantmartin2002 ## Deprecated ## Removed +- Remove native WebView2 loader support, superseded by the pure Go loader. This drops the embedded `WebView2Loader.dll` binaries and the `github.com/jchv/go-winloader` dependency. The `native_webview2loader` build tag is still accepted and no longer errors, but has no effect on v3 builds, in [PR](https://github.com/wailsapp/wails/pull/6031) by @Grantmartin2002 ## Security diff --git a/v3/go.mod b/v3/go.mod index c2e637ed48c..832db889888 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -115,7 +115,6 @@ require ( github.com/huandu/xstrings v1.5.0 // indirect github.com/jaypipes/pcidb v1.1.1 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 github.com/joho/godotenv v1.5.1 // indirect github.com/kevinburke/ssh_config v1.4.0 // indirect github.com/klauspost/compress v1.18.3 // indirect diff --git a/v3/go.sum b/v3/go.sum index f466e9964b6..cdb4f5eac2c 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -222,8 +222,6 @@ github.com/jaypipes/pcidb v1.1.1 h1:QmPhpsbmmnCwZmHeYAATxEaoRuiMAJusKYkUncMC0ro= github.com/jaypipes/pcidb v1.1.1/go.mod h1:x27LT2krrUgjf875KxQXKB0Ha/YXLdZRVmw6hH0G7g8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 h1:njuLRcjAuMKr7kI3D85AXWkw6/+v9PwtV6M6o11sWHQ= -github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= @@ -428,7 +426,6 @@ golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/v3/internal/webview2/pkg/edge/create_env_go.go b/v3/internal/webview2/pkg/edge/create_env_go.go index 252edc3e256..3bd5c1303f5 100644 --- a/v3/internal/webview2/pkg/edge/create_env_go.go +++ b/v3/internal/webview2/pkg/edge/create_env_go.go @@ -1,4 +1,4 @@ -//go:build windows && !native_webview2loader +//go:build windows package edge diff --git a/v3/internal/webview2/pkg/edge/create_env_native.go b/v3/internal/webview2/pkg/edge/create_env_native.go deleted file mode 100644 index 57259dd0ea9..00000000000 --- a/v3/internal/webview2/pkg/edge/create_env_native.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build windows && native_webview2loader - -package edge - -import ( - "fmt" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v3/internal/webview2/webviewloader" - - "golang.org/x/sys/windows" -) - -func createCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder string, environmentCompletedHandle *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, additionalBrowserArgs string) error { - browserPathPtr, err := windows.UTF16PtrFromString(browserExecutableFolder) - if err != nil { - return fmt.Errorf("Error calling UTF16PtrFromString for %s: %v", browserExecutableFolder, err) - } - - userPathPtr, err := windows.UTF16PtrFromString(userDataFolder) - if err != nil { - return fmt.Errorf("Error calling UTF16PtrFromString for %s: %v", userDataFolder, err) - } - - hr, err := webviewloader.CreateCoreWebView2EnvironmentWithOptions( - browserPathPtr, - userPathPtr, - uintptr(unsafe.Pointer(environmentCompletedHandle)), - additionalBrowserArgs, - ) - if err != nil { - return fmt.Errorf("Error calling CreateCoreWebView2EnvironmentWithOptions: %v", err) - } - - if hr != 0 { - return syscall.Errno(hr) - } - - return nil -} diff --git a/v3/internal/webview2/webviewloader/env_create.go b/v3/internal/webview2/webviewloader/env_create.go index 438161b9c20..1ebb02c0a7e 100644 --- a/v3/internal/webview2/webviewloader/env_create.go +++ b/v3/internal/webview2/webviewloader/env_create.go @@ -1,4 +1,4 @@ -//go:build windows && !native_webview2loader +//go:build windows package webviewloader diff --git a/v3/internal/webview2/webviewloader/env_create_completed.go b/v3/internal/webview2/webviewloader/env_create_completed.go index 2ade02465a7..9c8efa8e0c4 100644 --- a/v3/internal/webview2/webviewloader/env_create_completed.go +++ b/v3/internal/webview2/webviewloader/env_create_completed.go @@ -1,4 +1,4 @@ -//go:build windows && !native_webview2loader +//go:build windows package webviewloader diff --git a/v3/internal/webview2/webviewloader/env_create_options.go b/v3/internal/webview2/webviewloader/env_create_options.go index b42b2bb222f..f4030838405 100644 --- a/v3/internal/webview2/webviewloader/env_create_options.go +++ b/v3/internal/webview2/webviewloader/env_create_options.go @@ -1,4 +1,4 @@ -//go:build windows && !native_webview2loader +//go:build windows package webviewloader diff --git a/v3/internal/webview2/webviewloader/find_dll_installed.go b/v3/internal/webview2/webviewloader/find_dll_installed.go index 7ee171b2ad1..dd88757a19e 100644 --- a/v3/internal/webview2/webviewloader/find_dll_installed.go +++ b/v3/internal/webview2/webviewloader/find_dll_installed.go @@ -1,4 +1,4 @@ -//go:build windows && !native_webview2loader +//go:build windows package webviewloader diff --git a/v3/internal/webview2/webviewloader/native_module.go b/v3/internal/webview2/webviewloader/native_module.go deleted file mode 100644 index 3e02fe985e7..00000000000 --- a/v3/internal/webview2/webviewloader/native_module.go +++ /dev/null @@ -1,173 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import ( - "errors" - "fmt" - "os" - "sync" - "unsafe" - - "github.com/jchv/go-winloader" - - "golang.org/x/sys/windows" -) - -func init() { - preventEnvAndRegistryOverrides(nil, nil, "") -} - -var ( - memOnce sync.Once - memModule winloader.Module - memCreate winloader.Proc - memCompareBrowserVersions winloader.Proc - memGetAvailableCoreWebView2BrowserVersionString winloader.Proc - memErr error -) - -const ( - // https://referencesource.microsoft.com/#system.web/Util/hresults.cs,20 - E_FILENOTFOUND = 0x80070002 -) - -// CompareBrowserVersions will compare the 2 given versions and return: -// -// Less than zero: v1 < v2 -// zero: v1 == v2 -// Greater than zero: v1 > v2 -func CompareBrowserVersions(v1 string, v2 string) (int, error) { - _v1, err := windows.UTF16PtrFromString(v1) - if err != nil { - return 0, err - } - _v2, err := windows.UTF16PtrFromString(v2) - if err != nil { - return 0, err - } - - err = loadFromMemory() - if err != nil { - return 0, err - } - - var result int32 - _, _, err = memCompareBrowserVersions.Call( - uint64(uintptr(unsafe.Pointer(_v1))), - uint64(uintptr(unsafe.Pointer(_v2))), - uint64(uintptr(unsafe.Pointer(&result)))) - - if err != windows.ERROR_SUCCESS { - return 0, err - } - return int(result), nil -} - -// GetAvailableCoreWebView2BrowserVersionString returns version of the webview2 runtime. -// If path is empty, it will try to find installed webview2 is the system. -// If there is no version installed, a blank string is returned. -func GetAvailableCoreWebView2BrowserVersionString(path string) (string, error) { - if path != "" { - // The default implementation fails if CGO and a fixed browser path is used. It's caused by the go-winloader - // which loads the native DLL from memory. - // Use the new GoWebView2Loader in this case, in the future we will make GoWebView2Loader - // feature-complete and remove the use of the native DLL and go-winloader. - version, err := goGetAvailableCoreWebView2BrowserVersionString(path) - if errors.Is(err, errNoClientDLLFound) { - // WebView2 is not found - return "", nil - } else if err != nil { - return "", err - } - - return version, nil - } - - err := loadFromMemory() - if err != nil { - return "", err - } - - var browserPath *uint16 = nil - if path != "" { - browserPath, err = windows.UTF16PtrFromString(path) - if err != nil { - return "", fmt.Errorf("error calling UTF16PtrFromString for %s: %v", path, err) - } - } - - preventEnvAndRegistryOverrides(browserPath, nil, "") - var result *uint16 - res, _, err := memGetAvailableCoreWebView2BrowserVersionString.Call( - uint64(uintptr(unsafe.Pointer(browserPath))), - uint64(uintptr(unsafe.Pointer(&result)))) - - if res != 0 { - if res == E_FILENOTFOUND { - // WebView2 is not installed - return "", nil - } - - return "", fmt.Errorf("Unable to call GetAvailableCoreWebView2BrowserVersionString (%x): %w", res, err) - } - - version := windows.UTF16PtrToString(result) - windows.CoTaskMemFree(unsafe.Pointer(result)) - return version, nil -} - -// CreateCoreWebView2EnvironmentWithOptions tries to load WebviewLoader2 and -// call the CreateCoreWebView2EnvironmentWithOptions routine. -func CreateCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder *uint16, environmentCompletedHandle uintptr, additionalBrowserArgs string) (uintptr, error) { - err := loadFromMemory() - if err != nil { - return 0, err - } - - preventEnvAndRegistryOverrides(browserExecutableFolder, userDataFolder, additionalBrowserArgs) - res, _, _ := memCreate.Call( - uint64(uintptr(unsafe.Pointer(browserExecutableFolder))), - uint64(uintptr(unsafe.Pointer(userDataFolder))), - 0, - uint64(environmentCompletedHandle), - ) - return uintptr(res), nil -} - -func loadFromMemory() error { - var err error - // DLL is not available natively. Try loading embedded copy. - memOnce.Do(func() { - memModule, memErr = winloader.LoadFromMemory(WebView2Loader) - if memErr != nil { - err = fmt.Errorf("Unable to load WebView2Loader.dll from memory: %w", memErr) - return - } - memCreate = memModule.Proc("CreateCoreWebView2EnvironmentWithOptions") - memCompareBrowserVersions = memModule.Proc("CompareBrowserVersions") - memGetAvailableCoreWebView2BrowserVersionString = memModule.Proc("GetAvailableCoreWebView2BrowserVersionString") - }) - return err -} - -func preventEnvAndRegistryOverrides(browserFolder, userDataFolder *uint16, additionalBrowserArgs string) { - // Setting these env variables to empty string also prevents registry overrides because webview2loader - // checks for existence and not for empty value - os.Setenv("WEBVIEW2_PIPE_FOR_SCRIPT_DEBUGGER", "") - - // Set these overrides to the values or empty to prevent registry and external env overrides - os.Setenv("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", additionalBrowserArgs) - os.Setenv("WEBVIEW2_RELEASE_CHANNEL_PREFERENCE", "0") - os.Setenv("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", windows.UTF16PtrToString(browserFolder)) - os.Setenv("WEBVIEW2_USER_DATA_FOLDER", windows.UTF16PtrToString(userDataFolder)) -} - -func goGetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder string) (string, error) { - clientPath, err := findEmbeddedClientDll(browserExecutableFolder) - if err != nil { - return "", err - } - - return findEmbeddedBrowserVersion(clientPath) -} diff --git a/v3/internal/webview2/webviewloader/native_module_386.go b/v3/internal/webview2/webviewloader/native_module_386.go deleted file mode 100644 index e4ff44ff312..00000000000 --- a/v3/internal/webview2/webviewloader/native_module_386.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import _ "embed" - -//go:embed x86/WebView2Loader.dll -var WebView2Loader []byte diff --git a/v3/internal/webview2/webviewloader/native_module_amd64.go b/v3/internal/webview2/webviewloader/native_module_amd64.go deleted file mode 100644 index 27423ae8aa8..00000000000 --- a/v3/internal/webview2/webviewloader/native_module_amd64.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import _ "embed" - -//go:embed x64/WebView2Loader.dll -var WebView2Loader []byte diff --git a/v3/internal/webview2/webviewloader/native_module_arm64.go b/v3/internal/webview2/webviewloader/native_module_arm64.go deleted file mode 100644 index bba6a88cb1e..00000000000 --- a/v3/internal/webview2/webviewloader/native_module_arm64.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import _ "embed" - -//go:embed arm64/WebView2Loader.dll -var WebView2Loader []byte diff --git a/v3/internal/webview2/webviewloader/version.go b/v3/internal/webview2/webviewloader/version.go index 9e408752536..25edf4558ad 100644 --- a/v3/internal/webview2/webviewloader/version.go +++ b/v3/internal/webview2/webviewloader/version.go @@ -1,4 +1,4 @@ -//go:build windows && !native_webview2loader +//go:build windows package webviewloader