Compare commits

...

10 Commits

Author SHA1 Message Date
Lea\Anthony
9cb480f0f0 v2.0.0-beta.27 2021-12-27 19:40:56 +11:00
Lea\Anthony
6825a631f5 Commit MicrosoftEdgeWebview2Setup.exe 2021-12-27 19:40:19 +11:00
Lea\Anthony
39f91a030f v2.0.0-beta.26 2021-12-27 18:12:48 +11:00
Lea\Anthony
202e4d5be8 Actually commit sudo_mattn 2021-12-27 18:11:12 +11:00
Lea\Anthony
045e58778a Actually commit webview2runtime 2021-12-27 18:09:41 +11:00
Lea\Anthony
e375d60c67 Updated modules 2021-12-27 05:23:18 +11:00
Lea\Anthony
fcb5499d3a v2.0.0-beta.25 2021-12-27 05:21:17 +11:00
Lea\Anthony
dd5a54a8e0 Remove replace line 2021-12-27 05:21:17 +11:00
Lea Anthony
9f24a46b8a Merge pull request #1042 from flin7/patch-1
Add template for React
2021-12-26 21:19:53 +11:00
flin7
d7eaab97dd Add template for React 2021-12-26 17:21:19 +08:00
7 changed files with 404 additions and 3 deletions

View File

@@ -1,3 +1,3 @@
package internal
var Version = "v2.0.0-beta.24"
var Version = "v2.0.0-beta.27"

View File

@@ -80,5 +80,3 @@ require (
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
)
replace github.com/leaanthony/go-webview2 => C:\Users\leaan\Documents\wails-v2-beta\go-webview2

View File

@@ -118,6 +118,8 @@ github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQ
github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM=
github.com/leaanthony/go-common-file-dialog v1.0.3 h1:O0uGjKnWtdEADGrkg+TyAAbZylykMwwx/MNEXn9fp+Y=
github.com/leaanthony/go-common-file-dialog v1.0.3/go.mod h1:TGhEc9eSJgRsupZ+iH1ZgAOnEo9zp05cRH2j08RPrF0=
github.com/leaanthony/go-webview2 v1.0.2 h1:IjTbpAXUig33G3LUqf+8EClZutg2Z/C1cbxqhHKPxbU=
github.com/leaanthony/go-webview2 v1.0.2/go.mod h1:iX54IaVk1FnDqMuHJ47VYLPQOcVqQiOe9SJACt9CAbU=
github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4=
github.com/leaanthony/idgen v1.0.0 h1:IZreR+JGEzFV4yeVuBZA25gM0keUoFy+RDUldncQ+Jw=

View File

@@ -0,0 +1,232 @@
//go:build windows
// +build windows
// Original File (c) 2017 Yasuhiro Matsumoto: https://github.com/mattn/sudo/blob/master/win32.go
// License: https://github.com/mattn/sudo/blob/master/LICENSE
package webview2runtime
import (
"errors"
"fmt"
"os"
"syscall"
"unsafe"
)
var (
modshell32 = syscall.NewLazyDLL("shell32.dll")
procShellExecuteEx = modshell32.NewProc("ShellExecuteExW")
)
const (
_SEE_MASK_DEFAULT = 0x00000000
_SEE_MASK_CLASSNAME = 0x00000001
_SEE_MASK_CLASSKEY = 0x00000003
_SEE_MASK_IDLIST = 0x00000004
_SEE_MASK_INVOKEIDLIST = 0x0000000C
_SEE_MASK_ICON = 0x00000010
_SEE_MASK_HOTKEY = 0x00000020
_SEE_MASK_NOCLOSEPROCESS = 0x00000040
_SEE_MASK_CONNECTNETDRV = 0x00000080
_SEE_MASK_NOASYNC = 0x00000100
_SEE_MASK_FLAG_DDEWAIT = 0x00000100
_SEE_MASK_DOENVSUBST = 0x00000200
_SEE_MASK_FLAG_NO_UI = 0x00000400
_SEE_MASK_UNICODE = 0x00004000
_SEE_MASK_NO_CONSOLE = 0x00008000
_SEE_MASK_ASYNCOK = 0x00100000
_SEE_MASK_NOQUERYCLASSSTORE = 0x01000000
_SEE_MASK_HMONITOR = 0x00200000
_SEE_MASK_NOZONECHECKS = 0x00800000
_SEE_MASK_WAITFORINPUTIDLE = 0x02000000
_SEE_MASK_FLAG_LOG_USAGE = 0x04000000
_SEE_MASK_FLAG_HINST_IS_SITE = 0x08000000
)
const (
_ERROR_BAD_FORMAT = 11
)
const (
_SE_ERR_FNF = 2
_SE_ERR_PNF = 3
_SE_ERR_ACCESSDENIED = 5
_SE_ERR_OOM = 8
_SE_ERR_DLLNOTFOUND = 32
_SE_ERR_SHARE = 26
_SE_ERR_ASSOCINCOMPLETE = 27
_SE_ERR_DDETIMEOUT = 28
_SE_ERR_DDEFAIL = 29
_SE_ERR_DDEBUSY = 30
_SE_ERR_NOASSOC = 31
)
type (
dword uint32
hinstance syscall.Handle
hkey syscall.Handle
hwnd syscall.Handle
ulong uint32
lpctstr uintptr
lpvoid uintptr
)
// SHELLEXECUTEINFO struct
type _SHELLEXECUTEINFO struct {
cbSize dword
fMask ulong
hwnd hwnd
lpVerb lpctstr
lpFile lpctstr
lpParameters lpctstr
lpDirectory lpctstr
nShow int
hInstApp hinstance
lpIDList lpvoid
lpClass lpctstr
hkeyClass hkey
dwHotKey dword
hIconOrMonitor syscall.Handle
hProcess syscall.Handle
}
// ShellExecuteAndWait is version of ShellExecuteEx which want process
func ShellExecuteAndWait(hwnd hwnd, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
var lpctstrVerb, lpctstrParameters, lpctstrDirectory, lpctstrFile lpctstr
var err error
if len(lpOperation) != 0 {
lpctstrVerb, err = toUTF16(lpOperation)
if err != nil {
return err
}
}
if len(lpParameters) != 0 {
lpctstrParameters, err = toUTF16(lpParameters)
if err != nil {
return err
}
}
if len(lpDirectory) != 0 {
lpctstrDirectory, err = toUTF16(lpDirectory)
if err != nil {
return err
}
}
if len(lpDirectory) != 0 {
lpctstrFile, err = toUTF16(lpFile)
if err != nil {
return err
}
}
i := &_SHELLEXECUTEINFO{
fMask: _SEE_MASK_NOCLOSEPROCESS,
hwnd: hwnd,
lpVerb: lpctstrVerb,
lpFile: lpctstrFile,
lpParameters: lpctstrParameters,
lpDirectory: lpctstrDirectory,
nShow: nShowCmd,
}
i.cbSize = dword(unsafe.Sizeof(*i))
return ShellExecuteEx(i)
}
func toUTF16(lpOperation string) (lpctstr, error) {
result, err := syscall.UTF16PtrFromString(lpOperation)
if err != nil {
return 0, err
}
return lpctstr(unsafe.Pointer(result)), nil
}
// ShellExecuteNoWait is version of ShellExecuteEx which don't want process
func ShellExecuteNowait(hwnd hwnd, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
var lpctstrVerb, lpctstrParameters, lpctstrDirectory, lpctstrFile lpctstr
var err error
if len(lpOperation) != 0 {
lpctstrVerb, err = toUTF16(lpOperation)
if err != nil {
return err
}
}
if len(lpParameters) != 0 {
lpctstrParameters, err = toUTF16(lpParameters)
if err != nil {
return err
}
}
if len(lpDirectory) != 0 {
lpctstrDirectory, err = toUTF16(lpDirectory)
if err != nil {
return err
}
}
if len(lpDirectory) != 0 {
lpctstrFile, err = toUTF16(lpFile)
if err != nil {
return err
}
}
i := &_SHELLEXECUTEINFO{
fMask: _SEE_MASK_DEFAULT,
hwnd: hwnd,
lpVerb: lpctstrVerb,
lpFile: lpctstrFile,
lpParameters: lpctstrParameters,
lpDirectory: lpctstrDirectory,
nShow: nShowCmd,
}
i.cbSize = dword(unsafe.Sizeof(*i))
return ShellExecuteEx(i)
}
// ShellExecuteEx is Windows API
func ShellExecuteEx(pExecInfo *_SHELLEXECUTEINFO) error {
ret, _, _ := procShellExecuteEx.Call(uintptr(unsafe.Pointer(pExecInfo)))
if ret == 1 && pExecInfo.fMask&_SEE_MASK_NOCLOSEPROCESS != 0 {
s, e := syscall.WaitForSingleObject(pExecInfo.hProcess, syscall.INFINITE)
switch s {
case syscall.WAIT_OBJECT_0:
break
case syscall.WAIT_FAILED:
return os.NewSyscallError("WaitForSingleObject", e)
default:
return errors.New("Unexpected result from WaitForSingleObject")
}
}
errorMsg := ""
if pExecInfo.hInstApp != 0 && pExecInfo.hInstApp <= 32 {
switch int(pExecInfo.hInstApp) {
case _SE_ERR_FNF:
errorMsg = "The specified file was not found"
case _SE_ERR_PNF:
errorMsg = "The specified path was not found"
case _ERROR_BAD_FORMAT:
errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)"
case _SE_ERR_ACCESSDENIED:
errorMsg = "The operating system denied access to the specified file"
case _SE_ERR_ASSOCINCOMPLETE:
errorMsg = "The file name association is incomplete or invalid"
case _SE_ERR_DDEBUSY:
errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed"
case _SE_ERR_DDEFAIL:
errorMsg = "The DDE transaction failed"
case _SE_ERR_DDETIMEOUT:
errorMsg = "The DDE transaction could not be completed because the request timed out"
case _SE_ERR_DLLNOTFOUND:
errorMsg = "The specified DLL was not found"
case _SE_ERR_NOASSOC:
errorMsg = "There is no application associated with the given file name extension"
case _SE_ERR_OOM:
errorMsg = "There was not enough memory to complete the operation"
case _SE_ERR_SHARE:
errorMsg = "A sharing violation occurred"
default:
errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", pExecInfo.hInstApp)
}
} else {
return nil
}
return errors.New(errorMsg)
}

View File

@@ -0,0 +1,168 @@
//go:build windows
// +build windows
package webview2runtime
import (
_ "embed"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"syscall"
"unsafe"
)
//go:embed MicrosoftEdgeWebview2Setup.exe
var setupexe []byte
// Info contains all the information about an installation of the webview2 runtime.
type Info struct {
Location string
Name string
Version string
SilentUninstall string
}
// IsOlderThan returns true if the installed version is older than the given required version.
// Returns error if something goes wrong.
func (i *Info) IsOlderThan(requiredVersion string) (bool, error) {
var mod = syscall.NewLazyDLL("WebView2Loader.dll")
var CompareBrowserVersions = mod.NewProc("CompareBrowserVersions")
v1, err := syscall.UTF16PtrFromString(i.Version)
if err != nil {
return false, err
}
v2, err := syscall.UTF16PtrFromString(requiredVersion)
if err != nil {
return false, err
}
var result int = 9
_, _, err = CompareBrowserVersions.Call(uintptr(unsafe.Pointer(v1)), uintptr(unsafe.Pointer(v2)), uintptr(unsafe.Pointer(&result)))
if result < -1 || result > 1 {
return false, err
}
return result == -1, nil
}
func downloadBootstrapper() (string, error) {
bootstrapperURL := `https://go.microsoft.com/fwlink/p/?LinkId=2124703`
installer := filepath.Join(os.TempDir(), `MicrosoftEdgeWebview2Setup.exe`)
// Download installer
out, err := os.Create(installer)
defer out.Close()
if err != nil {
return "", err
}
resp, err := http.Get(bootstrapperURL)
defer resp.Body.Close()
if err != nil {
err = out.Close()
return "", err
}
_, err = io.Copy(out, resp.Body)
if err != nil {
return "", err
}
return installer, nil
}
// InstallUsingEmbeddedBootstrapper will download the bootstrapper from Microsoft and run it to install
// the latest version of the runtime.
// Returns true if the installer ran successfully.
// Returns an error if something goes wrong
func InstallUsingEmbeddedBootstrapper() (bool, error) {
installer := filepath.Join(os.TempDir(), `MicrosoftEdgeWebview2Setup.exe`)
err := os.WriteFile(installer, setupexe, 0755)
if err != nil {
return false, err
}
result, err := runInstaller(installer)
if err != nil {
return false, err
}
return result, os.Remove(installer)
}
// InstallUsingBootstrapper will extract the embedded bootstrapper from Microsoft and run it to install
// the latest version of the runtime.
// Returns true if the installer ran successfully.
// Returns an error if something goes wrong
func InstallUsingBootstrapper() (bool, error) {
installer, err := downloadBootstrapper()
if err != nil {
return false, err
}
result, err := runInstaller(installer)
if err != nil {
return false, err
}
return result, os.Remove(installer)
}
func runInstaller(installer string) (bool, error) {
err := ShellExecuteAndWait(0, "runas", installer, "", os.Getenv("TMP"), syscall.SW_NORMAL)
if err != nil {
fmt.Println(err)
return false, err
}
return true, nil
}
// Confirm will prompt the user with a message and OK / CANCEL buttons.
// Returns true if OK is selected by the user.
// Returns an error if something went wrong.
func Confirm(caption string, title string) (bool, error) {
var flags uint = 0x00000001 // MB_OKCANCEL
result, err := MessageBox(caption, title, flags)
if err != nil {
return false, err
}
return result == 1, nil
}
// Error will an error message to the user.
// Returns an error if something went wrong.
func Error(caption string, title string) error {
var flags uint = 0x00000010 // MB_ICONERROR
_, err := MessageBox(caption, title, flags)
return err
}
// MessageBox prompts the user with the given caption and title.
// Flags may be provided to customise the dialog.
// Returns an error if something went wrong.
func MessageBox(caption string, title string, flags uint) (int, error) {
captionUTF16, err := syscall.UTF16PtrFromString(caption)
if err != nil {
return -1, err
}
titleUTF16, err := syscall.UTF16PtrFromString(title)
if err != nil {
return -1, err
}
ret, _, _ := syscall.NewLazyDLL("user32.dll").NewProc("MessageBoxW").Call(
uintptr(0),
uintptr(unsafe.Pointer(captionUTF16)),
uintptr(unsafe.Pointer(titleUTF16)),
uintptr(flags))
return int(ret), nil
}
// OpenInstallerDownloadWebpage will open the browser on the WebView2 download page
func OpenInstallerDownloadWebpage() error {
cmd := exec.Command("rundll32", "url.dll,FileProtocolHandler", "https://developer.microsoft.com/en-us/microsoft-edge/webview2/")
return cmd.Run()
}

View File

@@ -32,6 +32,7 @@ Example: `wails init -n "Your Project Name" -t https://github.com/misitebao/wail
## React
- [wails-react-template](https://github.com/AlienRecall/wails-react-template) - A template using reactjs
- [wails-react-template](https://github.com/flin7/wails-react-template) - A minimal template for React that supports live development
## Svelte