Feature: set browser path (#1448)

* 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
This commit is contained in:
Nan0
2022-06-25 07:49:00 +10:00
committed by GitHub
parent c61ce1e2de
commit 2065600096
8 changed files with 90 additions and 10 deletions
@@ -352,8 +352,9 @@ func (f *Frontend) Quit() {
func (f *Frontend) setupChromium() {
chromium := edge.NewChromium()
f.chromium = chromium
if opts := f.frontendOptions.Windows; opts != nil && opts.WebviewUserDataPath != "" {
if opts := f.frontendOptions.Windows; opts != nil {
chromium.DataPath = opts.WebviewUserDataPath
chromium.BrowserPath = opts.WebviewBrowserPath
}
chromium.MessageCallback = f.processMessage
chromium.WebResourceRequestedCallback = f.processRequest
@@ -4,6 +4,7 @@
package edge
import (
"errors"
"log"
"os"
"path/filepath"
@@ -30,8 +31,9 @@ type Chromium struct {
environment *ICoreWebView2Environment
// Settings
Debug bool
DataPath string
Debug bool
DataPath string
BrowserPath string
// permissions
permissions map[CoreWebView2PermissionKind]CoreWebView2PermissionState
@@ -84,7 +86,27 @@ func (e *Chromium) Embed(hwnd uintptr) bool {
dataPath = filepath.Join(os.Getenv("AppData"), currentExeName)
}
res, err := createCoreWebView2EnvironmentWithOptions(nil, windows.StringToUTF16Ptr(dataPath), 0, e.envCompleted)
var browserPathPtr *uint16 = nil
if e.BrowserPath != "" {
if _, err := os.Stat(e.BrowserPath); !errors.Is(err, os.ErrNotExist) {
browserPathPtr, err = windows.UTF16PtrFromString(e.BrowserPath)
if err != nil {
log.Printf("Error calling UTF16PtrFromString for %s: %v", e.BrowserPath, err)
return false
}
} else {
log.Printf("Browser path %s does not exist", e.BrowserPath)
return false
}
}
dataPathPtr, err := windows.UTF16PtrFromString(dataPath)
if err != nil {
log.Printf("Error calling UTF16PtrFromString for %s: %v", dataPath, err)
return false
}
res, err := createCoreWebView2EnvironmentWithOptions(browserPathPtr, dataPathPtr, 0, e.envCompleted)
if err != nil {
log.Printf("Error calling Webview2Loader: %v", err)
return false
@@ -54,17 +54,26 @@ func CompareBrowserVersions(v1 string, v2 string) (int, error) {
return int(result), nil
}
// GetInstalledVersion returns the installed version of the webview2 runtime.
// 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 GetInstalledVersion() (string, error) {
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(nil))),
uint64(uintptr(unsafe.Pointer(browserPath))),
uint64(uintptr(unsafe.Pointer(&result))))
if res != 0 {
+1 -2
View File
@@ -28,8 +28,7 @@ func (i *Info) discover() error {
}
func checkWebView2() *packagemanager.Dependancy {
version, _ := webviewloader.GetInstalledVersion()
version, _ := webviewloader.GetWebviewVersion("")
installed := version != ""
return &packagemanager.Dependancy{
+14 -1
View File
@@ -3,6 +3,7 @@
package wv2installer
import (
"fmt"
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader"
"github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/options/windows"
@@ -24,7 +25,14 @@ func Process(appoptions *options.App) (string, error) {
}
installStatus := needsInstalling
installedVersion, err := webviewloader.GetInstalledVersion()
// Override version check for manually specified webview path if present
var webviewPath = ""
if opts := appoptions.Windows; opts != nil && opts.WebviewBrowserPath != "" {
webviewPath = opts.WebviewBrowserPath
}
installedVersion, err := webviewloader.GetWebviewVersion(webviewPath)
if err != nil {
return "", err
}
@@ -42,5 +50,10 @@ func Process(appoptions *options.App) (string, error) {
}
}
// Force error strategy if webview is manually specified
if webviewPath != "" {
return installedVersion, fmt.Errorf(messages.InvalidFixedWebview2)
}
return installedVersion, doInstallationStrategy(installStatus, messages)
}
+5
View File
@@ -12,6 +12,7 @@ type Messages struct {
DownloadPage string
PressOKToInstall string
ContactAdmin string
InvalidFixedWebview2 string
}
const (
@@ -71,6 +72,9 @@ type Options struct {
// If the path is not valid, a messagebox will be displayed with the error and the app will exit with error code.
WebviewUserDataPath string
// Path to the directory with WebView2 executables. If empty WebView2 installed in the system will be used.
WebviewBrowserPath string
// Dark/Light or System Default Theme
Theme Theme
@@ -104,5 +108,6 @@ func DefaultMessages() *Messages {
DownloadPage: "This application requires the WebView2 runtime. Press OK to open the download page. Minimum version required: ",
PressOKToInstall: "Press Ok to install.",
ContactAdmin: "The WebView2 runtime is required to run this application. Please contact your system administrator.",
InvalidFixedWebview2: "The WebView2 runtime is manually specified, but It is not valid. Check minimum required version and webview2 path.",
}
}
+17
View File
@@ -35,3 +35,20 @@ up to the user.
### Error
If no suitable runtime is found, an error is given to the user and no further action taken.
## Fixed version runtime
Another way of dealing with webview2 dependency is shipping it yourself.
You can download [fixed version runtime](https://developer.microsoft.com/ru-ru/microsoft-edge/webview2/#download-section) and bundle or download it with your application.
Also, you should specify path to fixed version of webview2 runtime in the `windows.Options` structure when launching wails.
```go
wails.Run(&options.App{
Windows: &windows.Options{
WebviewBrowserPath: "",
},
})
```
Note: When `WebviewBrowserPath` is specified, `error` strategy will be forced in case of minimal required version mismatch or invalid path to a runtime.
+14
View File
@@ -48,6 +48,7 @@ func main() {
DisableWindowIcon: false,
DisableFramelessWindowDecorations: false,
WebviewUserDataPath: "",
WebviewBrowserPath: "",
Theme: windows.SystemDefault,
CustomTheme: &windows.ThemeSettings{
DarkModeTitleBar: windows.RGB(20, 20, 20),
@@ -430,6 +431,19 @@ Type: string
This defines the path where the WebView2 stores the user data. If empty `%APPDATA%\[BinaryName.exe]` will be used.
### WebviewBrowserPath
Name: WebviewBrowserPath
Type: string
This defines the path to a directory with WebView2 executable files and libraries. If empty, webview2 installed in the system will be used.
Important information about distribution of fixed version runtime:
- [How to get and extract runtime](https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#details-about-the-fixed-version-runtime-distribution-mode)
- [Known issues for fixed version](https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#known-issues-for-fixed-version)
- [The path of fixed version of the WebView2 Runtime should not contain \Edge\Application\.](https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.1245.22#createcorewebview2environmentwithoptions)
### Theme
Name: Theme