mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 22:50:59 +08:00

* Added option to specify webview2 path * Added `manual` webview strategy * Update documentation * Fixed build with manual tag * Check for browser directory existence * Added version check for manually specified webview, removed fallback for installed webview in manual strategy * Update WebviewBrowserPath documentation * Replaced deprecated StringToUTF16Ptr * Return on error * Removed manual strategy, return error in wv2installer for fixed runtime * Removed manual strategy from CLI
124 lines
3.5 KiB
Go
124 lines
3.5 KiB
Go
package webviewloader
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"unsafe"
|
|
|
|
"github.com/jchv/go-winloader"
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
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
|
|
}
|
|
|
|
// GetWebviewVersion 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 GetWebviewVersion(path string) (string, error) {
|
|
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)
|
|
}
|
|
}
|
|
|
|
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, environmentOptions uintptr, environmentCompletedHandle uintptr) (uintptr, error) {
|
|
err := loadFromMemory()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
res, _, _ := memCreate.Call(
|
|
uint64(uintptr(unsafe.Pointer(browserExecutableFolder))),
|
|
uint64(uintptr(unsafe.Pointer(userDataFolder))),
|
|
uint64(environmentOptions),
|
|
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
|
|
}
|