Switch remote deploy to vendored source builds
Move remote deployment to a vendored source bundle built on the target host via Docker so redeploys no longer require local cross-compilation or host Go installation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
16
vendor/github.com/wailsapp/go-webview2/webviewloader/LICENSE
generated
vendored
Normal file
16
vendor/github.com/wailsapp/go-webview2/webviewloader/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
ISC License (ISC)
|
||||
|
||||
Copyright (c) 2020 John Chadwick
|
||||
Copyright (c) 2022 Wails Project Developers
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
19
vendor/github.com/wailsapp/go-webview2/webviewloader/README.md
generated
vendored
Normal file
19
vendor/github.com/wailsapp/go-webview2/webviewloader/README.md
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Webviewloader
|
||||
|
||||
Webviewloader is a port of [OpenWebView2Loader](https://github.com/jchv/OpenWebView2Loader) to Go.
|
||||
|
||||
It is intended to be feature-complete with the original WebView2Loader distributed with
|
||||
the WebView2 NuGet package, but some features are intentionally not implemented.
|
||||
|
||||
## Status
|
||||
|
||||
- [x] CompareBrowserVersions
|
||||
- [x] CreateCoreWebView2Environment
|
||||
- [x] CreateCoreWebView2EnvironmentWithOptions
|
||||
- [x] GetAvailableCoreWebView2BrowserVersionString
|
||||
|
||||
## Not implemented features
|
||||
|
||||
- Registry Overrides of Parameters
|
||||
- Env Variable Overrides of Parameters
|
||||
- Does not incorporate `GetCurrentPackageInfo` to search for an installed runtime
|
||||
176
vendor/github.com/wailsapp/go-webview2/webviewloader/env_create.go
generated
vendored
Normal file
176
vendor/github.com/wailsapp/go-webview2/webviewloader/env_create.go
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/go-webview2/pkg/combridge"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func init() {
|
||||
UsingGoWebview2Loader = true
|
||||
preventEnvAndRegistryOverrides()
|
||||
}
|
||||
|
||||
type webView2RunTimeType int32
|
||||
|
||||
const (
|
||||
webView2RunTimeTypeInstalled webView2RunTimeType = 0x00
|
||||
webView2RunTimeTypeRedistributable webView2RunTimeType = 0x01
|
||||
)
|
||||
|
||||
// CreateCoreWebView2Environment creates an evergreen WebView2 Environment using the installed WebView2 Runtime version.
|
||||
//
|
||||
// This is equivalent to running CreateCoreWebView2EnvironmentWithOptions without any options.
|
||||
// For more information, see CreateCoreWebView2EnvironmentWithOptions.
|
||||
func CreateCoreWebView2Environment(environmentCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) error {
|
||||
return CreateCoreWebView2EnvironmentWithOptions(environmentCompletedHandler)
|
||||
}
|
||||
|
||||
// CreateCoreWebView2EnvironmentWithOptions creates an environment with a custom version of WebView2 Runtime,
|
||||
// user data folder, and with or without additional options.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?#createcorewebview2environmentwithoptions
|
||||
func CreateCoreWebView2EnvironmentWithOptions(environmentCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, opts ...option) error {
|
||||
var params environmentOptions
|
||||
for _, opt := range opts {
|
||||
opt(¶ms)
|
||||
}
|
||||
|
||||
var err error
|
||||
var dllPath string
|
||||
var runtimeType webView2RunTimeType
|
||||
if browserExecutableFolder := params.browserExecutableFolder; browserExecutableFolder != "" {
|
||||
runtimeType = webView2RunTimeTypeRedistributable
|
||||
dllPath, err = findEmbeddedClientDll(browserExecutableFolder)
|
||||
} else {
|
||||
runtimeType = webView2RunTimeTypeInstalled
|
||||
dllPath, _, err = findInstalledClientDll(params.preferCanary)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return createWebViewEnvironmentWithClientDll(dllPath, runtimeType, params.userDataFolder,
|
||||
¶ms, environmentCompletedHandler)
|
||||
}
|
||||
|
||||
func createWebViewEnvironmentWithClientDll(lpLibFileName string, runtimeType webView2RunTimeType, userDataFolder string,
|
||||
envOptions *environmentOptions, envCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) error {
|
||||
|
||||
if !filepath.IsAbs(lpLibFileName) {
|
||||
return fmt.Errorf("lpLibFileName must be absolute")
|
||||
}
|
||||
|
||||
dll, err := windows.LoadDLL(lpLibFileName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Loading DLL failed: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
canUnloadProc, err := dll.FindProc("DllCanUnloadNow")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if r1, _, _ := canUnloadProc.Call(); r1 != windows.NO_ERROR {
|
||||
return
|
||||
}
|
||||
|
||||
dll.Release()
|
||||
}()
|
||||
|
||||
createProc, err := dll.FindProc("CreateWebViewEnvironmentWithOptionsInternal")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to find CreateWebViewEnvironmentWithOptionsInternal entrypoint: %w", err)
|
||||
}
|
||||
|
||||
userDataPtr, err := windows.UTF16PtrFromString(userDataFolder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
envOptionsCom := combridge.New2[iCoreWebView2EnvironmentOptions, iCoreWebView2EnvironmentOptions2](
|
||||
envOptions, envOptions)
|
||||
|
||||
defer envOptionsCom.Close()
|
||||
|
||||
envCompletedHandler = &environmentCreatedHandler{envCompletedHandler}
|
||||
envCompletedCom := combridge.New[iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](envCompletedHandler)
|
||||
defer envCompletedCom.Close()
|
||||
|
||||
preventEnvAndRegistryOverrides()
|
||||
|
||||
const unknown = 1
|
||||
hr, _, err := createProc.Call(
|
||||
uintptr(unknown),
|
||||
uintptr(runtimeType),
|
||||
uintptr(unsafe.Pointer(userDataPtr)),
|
||||
uintptr(envOptionsCom.Ref()),
|
||||
uintptr(envCompletedCom.Ref()))
|
||||
|
||||
if hr != 0 {
|
||||
if err == nil || err == windows.ERROR_SUCCESS {
|
||||
err = syscall.Errno(hr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type environmentCreatedHandler struct {
|
||||
originalHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler
|
||||
}
|
||||
|
||||
func (r *environmentCreatedHandler) EnvironmentCompleted(errorCode HRESULT, createdEnvironment *ICoreWebView2Environment) HRESULT {
|
||||
// The OpenWebview2Loader has some retry logic and retries once, didn't encounter any case when this would have been
|
||||
// needed during the development: https://github.com/jchv/OpenWebView2Loader/blob/master/Source/WebView2Loader.cpp#L202
|
||||
|
||||
if createdEnvironment != nil {
|
||||
// May or may not be necessary, but the official WebView2Loader seems to do it.
|
||||
iidICoreWebView2Environment := windows.GUID{
|
||||
Data1: 0xb96d755e,
|
||||
Data2: 0x0319,
|
||||
Data3: 0x4e92,
|
||||
Data4: [8]byte{0xa2, 0x96, 0x23, 0x43, 0x6f, 0x46, 0xa1, 0xfc},
|
||||
}
|
||||
|
||||
if err := createdEnvironment.QueryInterface(&iidICoreWebView2Environment, &createdEnvironment); err != nil {
|
||||
createdEnvironment = nil
|
||||
errNo, ok := err.(syscall.Errno)
|
||||
if !ok {
|
||||
errNo = syscall.Errno(windows.E_FAIL)
|
||||
}
|
||||
errorCode = HRESULT(errNo)
|
||||
}
|
||||
}
|
||||
|
||||
r.originalHandler.EnvironmentCompleted(errorCode, createdEnvironment)
|
||||
|
||||
if createdEnvironment != nil {
|
||||
createdEnvironment.Release()
|
||||
}
|
||||
|
||||
return HRESULT(windows.S_OK)
|
||||
}
|
||||
|
||||
func preventEnvAndRegistryOverrides() {
|
||||
// Setting these env variables to empty string also prevents registry overrides because webview2
|
||||
// checks for existence and not for empty value
|
||||
os.Setenv("WEBVIEW2_PIPE_FOR_SCRIPT_DEBUGGER", "")
|
||||
os.Setenv("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "")
|
||||
os.Setenv("WEBVIEW2_RELEASE_CHANNEL_PREFERENCE", "0")
|
||||
|
||||
// The following seems not be be required because those are only used by the webview2loader which
|
||||
// in this case is implemented on our own. But nevertheless set them to empty to be consistent.
|
||||
os.Setenv("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", "")
|
||||
os.Setenv("WEBVIEW2_USER_DATA_FOLDER", "")
|
||||
}
|
||||
42
vendor/github.com/wailsapp/go-webview2/webviewloader/env_create_completed.go
generated
vendored
Normal file
42
vendor/github.com/wailsapp/go-webview2/webviewloader/env_create_completed.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/go-webview2/pkg/combridge"
|
||||
)
|
||||
|
||||
// HRESULT
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values
|
||||
type HRESULT int32
|
||||
|
||||
// ICoreWebView2Environment Represents the WebView2 Environment
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environment
|
||||
type ICoreWebView2Environment = combridge.IUnknownImpl
|
||||
|
||||
// ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler receives the WebView2Environment created using CreateCoreWebView2Environment.
|
||||
type ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler interface {
|
||||
// EnvironmentCompleted is invoked to receive the created WebView2Environment
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2createcorewebview2environmentcompletedhandler?#invoke
|
||||
EnvironmentCompleted(errorCode HRESULT, createdEnvironment *ICoreWebView2Environment) HRESULT
|
||||
}
|
||||
|
||||
type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler interface {
|
||||
combridge.IUnknown
|
||||
ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler
|
||||
}
|
||||
|
||||
func init() {
|
||||
combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](
|
||||
"{4e8a3389-c9d8-4bd2-b6b5-124fee6cc14d}",
|
||||
_iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke,
|
||||
)
|
||||
}
|
||||
|
||||
func _iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke(this uintptr, errorCode HRESULT, env *combridge.IUnknownImpl) uintptr {
|
||||
res := combridge.Resolve[iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](this).EnvironmentCompleted(errorCode, env)
|
||||
return uintptr(res)
|
||||
}
|
||||
276
vendor/github.com/wailsapp/go-webview2/webviewloader/env_create_options.go
generated
vendored
Normal file
276
vendor/github.com/wailsapp/go-webview2/webviewloader/env_create_options.go
generated
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/go-webview2/pkg/combridge"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// WithBrowserExecutableFolder to specify whether WebView2 controls use a fixed or installed version
|
||||
// of the WebView2 Runtime that exists on a user machine.
|
||||
//
|
||||
// To use a fixed version of the WebView2 Runtime,
|
||||
// pass the folder path that contains the fixed version of the WebView2 Runtime.
|
||||
// BrowserExecutableFolder supports both relative (to the application's executable) and absolute files paths.
|
||||
// To create WebView2 controls that use the installed version of the WebView2 Runtime that exists on user
|
||||
// machines, pass a empty string to WithBrowserExecutableFolder. In this scenario, the API tries to find a
|
||||
// compatible version of the WebView2 Runtime that is installed on the user machine (first at the machine level,
|
||||
// and then per user) using the selected channel preference. The path of fixed version of the WebView2 Runtime
|
||||
// should not contain \Edge\Application\. When such a path is used, the API fails with HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).
|
||||
func WithBrowserExecutableFolder(folder string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.browserExecutableFolder = folder
|
||||
}
|
||||
}
|
||||
|
||||
// WithUserDataFolder specifies to user data folder location for WebView2
|
||||
//
|
||||
// You may specify the userDataFolder to change the default user data folder location for WebView2.
|
||||
// The path is either an absolute file path or a relative file path that is interpreted as relative
|
||||
// to the compiled code for the current process.
|
||||
// Dhe default user data ({Executable File Name}.WebView2) folder is created in the same directory
|
||||
// next to the compiled code for the app. WebView2 creation fails if the compiled code is running
|
||||
// in a directory in which the process does not have permission to create a new directory.
|
||||
// The app is responsible to clean up the associated user data folder when it is done.
|
||||
func WithUserDataFolder(folder string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.userDataFolder = folder
|
||||
}
|
||||
}
|
||||
|
||||
// WithAdditionalBrowserArguments changes the behavior of the WebView.
|
||||
//
|
||||
// The arguments are passed to the
|
||||
// browser process as part of the command. For more information about
|
||||
// using command-line switches with Chromium browser processes, navigate to
|
||||
// [Run Chromium with Flags][ChromiumDevelopersHowTosRunWithFlags].
|
||||
// The value appended to a switch is appended to the browser process, for
|
||||
// example, in `--edge-webview-switches=xxx` the value is `xxx`. If you
|
||||
// specify a switch that is important to WebView functionality, it is
|
||||
// ignored, for example, `--user-data-dir`. Specific features are disabled
|
||||
// internally and blocked from being enabled. If a switch is specified
|
||||
// multiple times, only the last instance is used.
|
||||
//
|
||||
// \> [!NOTE]\n\> A merge of the different values of the same switch is not attempted,
|
||||
// except for disabled and enabled features. The features specified by
|
||||
// `--enable-features` and `--disable-features` are merged with simple
|
||||
// logic.\n\> * The features is the union of the specified features
|
||||
// and built-in features. If a feature is disabled, it is removed from the
|
||||
// enabled features list.
|
||||
//
|
||||
// If you specify command-line switches and use the
|
||||
// `additionalBrowserArguments` parameter, the `--edge-webview-switches`
|
||||
// value takes precedence and is processed last. If a switch fails to
|
||||
// parse, the switch is ignored. The default state for the operation is
|
||||
// to run the browser process with no extra flags.
|
||||
//
|
||||
// [ChromiumDevelopersHowTosRunWithFlags]: https://www.chromium.org/developers/how-tos/run-chromium-with-flags "Run Chromium with flags | The Chromium Projects"
|
||||
func WithAdditionalBrowserArguments(args string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.additionalBrowserArguments = args
|
||||
}
|
||||
}
|
||||
|
||||
// WithLanguage sets the default display language for WebView.
|
||||
//
|
||||
// It applies to browser UI such as
|
||||
// context menu and dialogs. It also applies to the `accept-languages` HTTP
|
||||
// header that WebView sends to websites. It is in the format of
|
||||
//
|
||||
// `language[-country]` where `language` is the 2-letter code from
|
||||
// [ISO 639][ISO639LanguageCodesHtml]
|
||||
// and `country` is the
|
||||
// 2-letter code from
|
||||
// [ISO 3166][ISOStandard72482Html].
|
||||
//
|
||||
// [ISO639LanguageCodesHtml]: https://www.iso.org/iso-639-language-codes.html "ISO 639 | ISO"
|
||||
// [ISOStandard72482Html]: https://www.iso.org/standard/72482.html "ISO 3166-1:2020 | ISO"
|
||||
func WithLanguage(lang string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.language = lang
|
||||
}
|
||||
}
|
||||
|
||||
// WithTargetCompatibleBrowserVersion secifies the version of the WebView2 Runtime binaries required to be
|
||||
// compatible with your app.
|
||||
//
|
||||
// This defaults to the WebView2 Runtime version
|
||||
// that corresponds with the version of the SDK the app is using. The
|
||||
// format of this value is the same as the format of the
|
||||
// `BrowserVersionString` property and other `BrowserVersion` values. Only
|
||||
// the version part of the `BrowserVersion` value is respected. The channel
|
||||
// suffix, if it exists, is ignored. The version of the WebView2 Runtime
|
||||
// binaries actually used may be different from the specified
|
||||
// `TargetCompatibleBrowserVersion`. The binaries are only guaranteed to be
|
||||
// compatible. Verify the actual version on the `BrowserVersionString`
|
||||
// property on the `ICoreWebView2Environment`.
|
||||
func WithTargetCompatibleBrowserVersion(version string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.targetCompatibleBrowserVersion = version
|
||||
}
|
||||
}
|
||||
|
||||
// WithAllowSingleSignOnUsingOSPrimaryAccount is used to enable
|
||||
// single sign on with Azure Active Directory (AAD) and personal Microsoft
|
||||
// Account (MSA) resources inside WebView. All AAD accounts, connected to
|
||||
// Windows and shared for all apps, are supported. For MSA, SSO is only enabled
|
||||
// for the account associated for Windows account login, if any.
|
||||
// Default is disabled. Universal Windows Platform apps must also declare
|
||||
// `enterpriseCloudSSO`
|
||||
// [Restricted capabilities][WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities]
|
||||
// for the single sign on (SSO) to work.
|
||||
//
|
||||
// [WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities]: /windows/uwp/packaging/app-capability-declarations\#restricted-capabilities "Restricted capabilities - App capability declarations | Microsoft Docs"
|
||||
func WithAllowSingleSignOnUsingOSPrimaryAccount(allow bool) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.allowSingleSignOnUsingOSPrimaryAccount = allow
|
||||
}
|
||||
}
|
||||
|
||||
// WithExclusiveUserDataFolderAccess specifies that the WebView environment
|
||||
// obtains exclusive access to the user data folder.
|
||||
//
|
||||
// If the user data folder is already being used by another WebView environment with a
|
||||
// different value for `ExclusiveUserDataFolderAccess` property, the creation of a WebView2Controller
|
||||
// using the environment object will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
|
||||
// When set as TRUE, no other WebView can be created from other processes using WebView2Environment
|
||||
// objects with the same UserDataFolder. This prevents other processes from creating WebViews
|
||||
// which share the same browser process instance, since sharing is performed among
|
||||
// WebViews that have the same UserDataFolder. When another process tries to create a
|
||||
// WebView2Controller from an WebView2Environment object created with the same user data folder,
|
||||
// it will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
|
||||
func WithExclusiveUserDataFolderAccess(exclusive bool) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.exclusiveUserDataFolderAccess = exclusive
|
||||
}
|
||||
}
|
||||
|
||||
type option func(*environmentOptions)
|
||||
|
||||
var _ iCoreWebView2EnvironmentOptions = &environmentOptions{}
|
||||
var _ iCoreWebView2EnvironmentOptions2 = &environmentOptions{}
|
||||
|
||||
type environmentOptions struct {
|
||||
browserExecutableFolder string
|
||||
userDataFolder string
|
||||
preferCanary bool
|
||||
|
||||
additionalBrowserArguments string
|
||||
language string
|
||||
targetCompatibleBrowserVersion string
|
||||
allowSingleSignOnUsingOSPrimaryAccount bool
|
||||
exclusiveUserDataFolderAccess bool
|
||||
}
|
||||
|
||||
func (o *environmentOptions) AdditionalBrowserArguments() string {
|
||||
return o.additionalBrowserArguments
|
||||
}
|
||||
|
||||
func (o *environmentOptions) Language() string {
|
||||
return o.language
|
||||
}
|
||||
|
||||
func (o *environmentOptions) TargetCompatibleBrowserVersion() string {
|
||||
v := o.targetCompatibleBrowserVersion
|
||||
if v == "" {
|
||||
v = kMinimumCompatibleVersion
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (o *environmentOptions) AllowSingleSignOnUsingOSPrimaryAccount() bool {
|
||||
return o.allowSingleSignOnUsingOSPrimaryAccount
|
||||
}
|
||||
|
||||
func (o *environmentOptions) ExclusiveUserDataFolderAccess() bool {
|
||||
return o.exclusiveUserDataFolderAccess
|
||||
}
|
||||
|
||||
type iCoreWebView2EnvironmentOptions interface {
|
||||
combridge.IUnknown
|
||||
|
||||
AdditionalBrowserArguments() string
|
||||
Language() string
|
||||
TargetCompatibleBrowserVersion() string
|
||||
AllowSingleSignOnUsingOSPrimaryAccount() bool
|
||||
}
|
||||
|
||||
type iCoreWebView2EnvironmentOptions2 interface {
|
||||
combridge.IUnknown
|
||||
|
||||
ExclusiveUserDataFolderAccess() bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions](
|
||||
"{2fde08a8-1e9a-4766-8c05-95a9ceb9d1c5}",
|
||||
_iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
_iCoreWebView2EnvironmentOptionsLanguage,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
_iCoreWebView2EnvironmentTargetCompatibleBrowserVersion,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
_iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
)
|
||||
|
||||
combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions2](
|
||||
"{ff85c98a-1ba7-4a6b-90c8-2b752c89e9e2}",
|
||||
_iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
)
|
||||
}
|
||||
func _iCoreWebView2EnvironmentOptionsNOP(this uintptr) uintptr {
|
||||
return uintptr(windows.S_FALSE)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments(this uintptr, value **uint16) uintptr {
|
||||
v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AdditionalBrowserArguments()
|
||||
*value = stringToOleString(v)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentOptionsLanguage(this uintptr, value **uint16) uintptr {
|
||||
args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).Language()
|
||||
*value = stringToOleString(args)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentTargetCompatibleBrowserVersion(this uintptr, value **uint16) uintptr {
|
||||
args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).TargetCompatibleBrowserVersion()
|
||||
*value = stringToOleString(args)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount(this uintptr, value *int32) uintptr {
|
||||
v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AllowSingleSignOnUsingOSPrimaryAccount()
|
||||
*value = boolToInt(v)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess(this uintptr, value *int32) uintptr {
|
||||
v := combridge.Resolve[iCoreWebView2EnvironmentOptions2](this).ExclusiveUserDataFolderAccess()
|
||||
*value = boolToInt(v)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func stringToOleString(v string) *uint16 {
|
||||
wstr := utf16.Encode([]rune(v + "\x00"))
|
||||
lwstr := len(wstr)
|
||||
ptr := (*uint16)(coTaskMemAlloc(2 * lwstr))
|
||||
|
||||
copy(unsafe.Slice(ptr, lwstr), wstr)
|
||||
|
||||
return ptr
|
||||
}
|
||||
|
||||
func boolToInt(v bool) int32 {
|
||||
if v {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
74
vendor/github.com/wailsapp/go-webview2/webviewloader/find_dll.go
generated
vendored
Normal file
74
vendor/github.com/wailsapp/go-webview2/webviewloader/find_dll.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
//go:build windows
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
var (
|
||||
errNoClientDLLFound = errors.New("no webview2 found")
|
||||
)
|
||||
|
||||
func findEmbeddedBrowserVersion(filename string) (string, error) {
|
||||
block, err := getFileVersionInfo(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
info, err := verQueryValueString(block, "\\StringFileInfo\\040904B0\\ProductVersion")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func findEmbeddedClientDll(embeddedEdgeSubFolder string) (outClientPath string, err error) {
|
||||
if !filepath.IsAbs(embeddedEdgeSubFolder) {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
embeddedEdgeSubFolder = filepath.Join(filepath.Dir(exe), embeddedEdgeSubFolder)
|
||||
}
|
||||
|
||||
return findClientDllInFolder(embeddedEdgeSubFolder)
|
||||
}
|
||||
|
||||
func findClientDllInFolder(folder string) (string, error) {
|
||||
arch := ""
|
||||
switch runtime.GOARCH {
|
||||
case "arm64":
|
||||
arch = "arm64"
|
||||
case "amd64":
|
||||
arch = "x64"
|
||||
case "386":
|
||||
arch = "x86"
|
||||
default:
|
||||
return "", fmt.Errorf("Unsupported architecture")
|
||||
}
|
||||
|
||||
dllPath := filepath.Join(folder, "EBWebView", arch, "EmbeddedBrowserWebView.dll")
|
||||
if _, err := os.Stat(dllPath); err != nil {
|
||||
return "", mapFindErr(err)
|
||||
}
|
||||
return dllPath, nil
|
||||
}
|
||||
|
||||
func mapFindErr(err error) error {
|
||||
if errors.Is(err, registry.ErrNotExist) {
|
||||
return errNoClientDLLFound
|
||||
}
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return errNoClientDLLFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
94
vendor/github.com/wailsapp/go-webview2/webviewloader/find_dll_installed.go
generated
vendored
Normal file
94
vendor/github.com/wailsapp/go-webview2/webviewloader/find_dll_installed.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
const (
|
||||
kNumChannels = 4
|
||||
kInstallKeyPath = "Software\\Microsoft\\EdgeUpdate\\ClientState\\"
|
||||
kMinimumCompatibleVersion = "86.0.616.0"
|
||||
)
|
||||
|
||||
var (
|
||||
kChannelName = [kNumChannels]string{
|
||||
"", "beta", "dev", "canary", // "internal"
|
||||
}
|
||||
|
||||
kChannelUuid = [kNumChannels]string{
|
||||
"{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}",
|
||||
"{2CD8A007-E189-409D-A2C8-9AF4EF3C72AA}",
|
||||
"{0D50BFEC-CD6A-4F9A-964C-C7416E3ACB10}",
|
||||
"{65C35B14-6C1D-4122-AC46-7148CC9D6497}",
|
||||
//"{BE59E8FD-089A-411B-A3B0-051D9E417818}",
|
||||
}
|
||||
|
||||
minimumCompatibleVersion, _ = parseVersion(kMinimumCompatibleVersion)
|
||||
)
|
||||
|
||||
func findInstalledClientDll(preferCanary bool) (clientPath string, version *version, err error) {
|
||||
for i := 0; i < kNumChannels; i++ {
|
||||
channel := i
|
||||
if preferCanary {
|
||||
channel = (kNumChannels - 1) - i
|
||||
}
|
||||
|
||||
key := kInstallKeyPath + kChannelUuid[channel]
|
||||
for _, checkSystem := range []bool{true, false} {
|
||||
clientPath, version, err := findInstalledClientDllForChannel(key, checkSystem)
|
||||
if err == errNoClientDLLFound {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
version.channel = kChannelName[channel]
|
||||
return clientPath, version, nil
|
||||
}
|
||||
}
|
||||
return "", nil, errNoClientDLLFound
|
||||
}
|
||||
|
||||
func findInstalledClientDllForChannel(subKey string, system bool) (clientPath string, clientVersion *version, err error) {
|
||||
key := registry.LOCAL_MACHINE
|
||||
if !system {
|
||||
key = registry.CURRENT_USER
|
||||
}
|
||||
|
||||
regKey, err := registry.OpenKey(key, subKey, registry.READ|registry.WOW64_32KEY)
|
||||
if err != nil {
|
||||
return "", nil, mapFindErr(err)
|
||||
}
|
||||
defer regKey.Close()
|
||||
|
||||
embeddedEdgeSubFolder, _, err := regKey.GetStringValue("EBWebView")
|
||||
if err != nil {
|
||||
return "", nil, mapFindErr(err)
|
||||
}
|
||||
|
||||
if embeddedEdgeSubFolder == "" {
|
||||
return "", nil, errNoClientDLLFound
|
||||
}
|
||||
|
||||
versionString := filepath.Base(embeddedEdgeSubFolder)
|
||||
version, err := parseVersion(versionString)
|
||||
if err != nil {
|
||||
return "", nil, errNoClientDLLFound
|
||||
}
|
||||
|
||||
if version.compare(minimumCompatibleVersion) < 0 {
|
||||
return "", nil, errNoClientDLLFound
|
||||
}
|
||||
|
||||
dllPath, err := findEmbeddedClientDll(embeddedEdgeSubFolder)
|
||||
if err != nil {
|
||||
return "", nil, mapFindErr(err)
|
||||
}
|
||||
|
||||
return dllPath, &version, nil
|
||||
}
|
||||
173
vendor/github.com/wailsapp/go-webview2/webviewloader/native_module.go
generated
vendored
Normal file
173
vendor/github.com/wailsapp/go-webview2/webviewloader/native_module.go
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
//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)
|
||||
}
|
||||
8
vendor/github.com/wailsapp/go-webview2/webviewloader/native_module_386.go
generated
vendored
Normal file
8
vendor/github.com/wailsapp/go-webview2/webviewloader/native_module_386.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
//go:build windows && native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed x86/WebView2Loader.dll
|
||||
var WebView2Loader []byte
|
||||
8
vendor/github.com/wailsapp/go-webview2/webviewloader/native_module_amd64.go
generated
vendored
Normal file
8
vendor/github.com/wailsapp/go-webview2/webviewloader/native_module_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
//go:build windows && native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed x64/WebView2Loader.dll
|
||||
var WebView2Loader []byte
|
||||
8
vendor/github.com/wailsapp/go-webview2/webviewloader/native_module_arm64.go
generated
vendored
Normal file
8
vendor/github.com/wailsapp/go-webview2/webviewloader/native_module_arm64.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
//go:build windows && native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed arm64/WebView2Loader.dll
|
||||
var WebView2Loader []byte
|
||||
143
vendor/github.com/wailsapp/go-webview2/webviewloader/syscall.go
generated
vendored
Normal file
143
vendor/github.com/wailsapp/go-webview2/webviewloader/syscall.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
//go:build windows
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
procGlobalAlloc = modkernel32.NewProc("GlobalAlloc")
|
||||
procGlobalFree = modkernel32.NewProc("GlobalFree")
|
||||
|
||||
modversion = windows.NewLazySystemDLL("version.dll")
|
||||
procGetFileVersionInfoSize = modversion.NewProc("GetFileVersionInfoSizeW")
|
||||
procGetFileVersionInfo = modversion.NewProc("GetFileVersionInfoW")
|
||||
procVerQueryValue = modversion.NewProc("VerQueryValueW")
|
||||
|
||||
modole32 = windows.NewLazySystemDLL("ole32.dll")
|
||||
procCoTaskMemAlloc = modole32.NewProc("CoTaskMemAlloc")
|
||||
)
|
||||
|
||||
func getFileVersionInfo(path string) ([]byte, error) {
|
||||
lptstrFilename, err := syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
size, _, err := procGetFileVersionInfoSize.Call(
|
||||
uintptr(unsafe.Pointer(lptstrFilename)),
|
||||
0,
|
||||
)
|
||||
|
||||
err = maskErrorSuccess(err)
|
||||
if size == 0 && err == nil {
|
||||
err = fmt.Errorf("GetFileVersionInfoSize failed")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := make([]byte, size)
|
||||
ret, _, err := procGetFileVersionInfo.Call(
|
||||
uintptr(unsafe.Pointer(lptstrFilename)),
|
||||
0,
|
||||
uintptr(size),
|
||||
uintptr(unsafe.Pointer(&data[0])),
|
||||
)
|
||||
|
||||
err = maskErrorSuccess(err)
|
||||
if ret == 0 && err == nil {
|
||||
err = fmt.Errorf("GetFileVersionInfo failed")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func verQueryValueString(block []byte, subBlock string) (string, error) {
|
||||
// Allocate memory from native side to make sure the block doesn't get moved
|
||||
// because we get a pointer into that memory block from the native verQueryValue
|
||||
// call back.
|
||||
pBlock := globalAlloc(0, uint32(len(block)))
|
||||
defer globalFree(unsafe.Pointer(pBlock))
|
||||
|
||||
// Copy the memory region into native side memory
|
||||
copy(unsafe.Slice((*byte)(pBlock), len(block)), block)
|
||||
|
||||
lpSubBlock, err := syscall.UTF16PtrFromString(subBlock)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var lplpBuffer unsafe.Pointer
|
||||
var puLen uint
|
||||
ret, _, err := procVerQueryValue.Call(
|
||||
uintptr(pBlock),
|
||||
uintptr(unsafe.Pointer(lpSubBlock)),
|
||||
uintptr(unsafe.Pointer(&lplpBuffer)),
|
||||
uintptr(unsafe.Pointer(&puLen)),
|
||||
)
|
||||
|
||||
err = maskErrorSuccess(err)
|
||||
if ret == 0 && err == nil {
|
||||
err = fmt.Errorf("VerQueryValue failed")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if puLen <= 1 {
|
||||
return "", nil
|
||||
}
|
||||
puLen -= 1 // Remove Null-Terminator
|
||||
|
||||
wchar := unsafe.Slice((*uint16)(lplpBuffer), puLen)
|
||||
return string(utf16.Decode(wchar)), nil
|
||||
}
|
||||
|
||||
func globalAlloc(uFlags uint, dwBytes uint32) unsafe.Pointer {
|
||||
ret, _, _ := procGlobalAlloc.Call(
|
||||
uintptr(uFlags),
|
||||
uintptr(dwBytes))
|
||||
|
||||
if ret == 0 {
|
||||
panic("globalAlloc failed")
|
||||
}
|
||||
|
||||
return unsafe.Pointer(ret)
|
||||
}
|
||||
|
||||
func globalFree(data unsafe.Pointer) {
|
||||
ret, _, _ := procGlobalFree.Call(uintptr(data))
|
||||
if ret != 0 {
|
||||
panic("globalFree failed")
|
||||
}
|
||||
}
|
||||
|
||||
func maskErrorSuccess(err error) error {
|
||||
if err == windows.ERROR_SUCCESS {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func coTaskMemAlloc(size int) unsafe.Pointer {
|
||||
ret, _, _ := procCoTaskMemAlloc.Call(
|
||||
uintptr(size))
|
||||
|
||||
if ret == 0 {
|
||||
panic("coTaskMemAlloc failed")
|
||||
}
|
||||
return unsafe.Pointer(ret)
|
||||
}
|
||||
150
vendor/github.com/wailsapp/go-webview2/webviewloader/version.go
generated
vendored
Normal file
150
vendor/github.com/wailsapp/go-webview2/webviewloader/version.go
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// UsingGoWebview2Loader is set to true when the go webview2loader is used.
|
||||
var UsingGoWebview2Loader bool
|
||||
|
||||
// CompareBrowserVersions will compare the 2 given versions and return:
|
||||
//
|
||||
// -1 = v1 < v2
|
||||
// 0 = v1 == v2
|
||||
// 1 = v1 > v2
|
||||
func CompareBrowserVersions(v1 string, v2 string) (int, error) {
|
||||
v, err := parseVersion(v1)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("v1 invalid: %w", err)
|
||||
}
|
||||
|
||||
w, err := parseVersion(v2)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("v2 invalid: %w", err)
|
||||
}
|
||||
|
||||
return v.compare(w), nil
|
||||
}
|
||||
|
||||
// GetAvailableCoreWebView2BrowserVersionString get the browser version info including channel name
|
||||
// if it is the WebView2 Runtime.
|
||||
// Channel names are Beta, Dev, and Canary.
|
||||
func GetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder string) (string, error) {
|
||||
if browserExecutableFolder != "" {
|
||||
clientPath, err := findEmbeddedClientDll(browserExecutableFolder)
|
||||
if errors.Is(err, errNoClientDLLFound) {
|
||||
// WebView2 is not found
|
||||
return "", nil
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return findEmbeddedBrowserVersion(clientPath)
|
||||
}
|
||||
|
||||
_, version, err := findInstalledClientDll(false)
|
||||
if errors.Is(err, errNoClientDLLFound) {
|
||||
return "", nil
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return version.String(), nil
|
||||
}
|
||||
|
||||
type version struct {
|
||||
major int
|
||||
minor int
|
||||
patch int
|
||||
build int
|
||||
|
||||
channel string
|
||||
}
|
||||
|
||||
func (v version) String() string {
|
||||
vv := fmt.Sprintf("%d.%d.%d.%d", v.major, v.minor, v.patch, v.build)
|
||||
if v.channel != "" {
|
||||
vv += " " + v.channel
|
||||
}
|
||||
|
||||
return vv
|
||||
}
|
||||
|
||||
func (v version) compare(o version) int {
|
||||
if c := compareInt(v.major, o.major); c != 0 {
|
||||
return c
|
||||
}
|
||||
if c := compareInt(v.minor, o.minor); c != 0 {
|
||||
return c
|
||||
}
|
||||
if c := compareInt(v.patch, o.patch); c != 0 {
|
||||
return c
|
||||
}
|
||||
return compareInt(v.build, o.build)
|
||||
}
|
||||
|
||||
func parseVersion(v string) (version, error) {
|
||||
var p version
|
||||
|
||||
// Split away channel information...
|
||||
if i := strings.Index(v, " "); i > 0 {
|
||||
p.channel = v[i+1:]
|
||||
v = v[:i]
|
||||
}
|
||||
|
||||
vv := strings.Split(v, ".")
|
||||
if len(vv) > 4 {
|
||||
return p, fmt.Errorf("too many version parts")
|
||||
}
|
||||
|
||||
var err error
|
||||
vv, p.major, err = parseInt(vv)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("bad major version: %w", err)
|
||||
}
|
||||
|
||||
vv, p.minor, err = parseInt(vv)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("bad minor version: %w", err)
|
||||
}
|
||||
|
||||
vv, p.patch, err = parseInt(vv)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("bad patch version: %w", err)
|
||||
}
|
||||
|
||||
_, p.build, err = parseInt(vv)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("bad build version: %w", err)
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func parseInt(v []string) ([]string, int, error) {
|
||||
if len(v) == 0 {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
p, err := strconv.ParseInt(v[0], 10, 32)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v[1:], int(p), nil
|
||||
}
|
||||
|
||||
func compareInt(v1, v2 int) int {
|
||||
if v1 == v2 {
|
||||
return 0
|
||||
}
|
||||
if v1 < v2 {
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user