Files
OpsLog/webview2_windows.go
T
rouggy f3b607b15a chore(startup): name the WebView2 runtime and mark every milestone
His startup.log stops after 'data dir ok', which rules out the two faults
already covered and leaves the window creation itself — where a missing
WebView2 runtime lands, sometimes as a silent exit rather than an error
anyone can print.

So the runtime's version is read from where it registers itself (both
hives, and the 32-bit view where a per-machine install usually lands) and
written BEFORE the window is attempted: 'WebView2: not found' answers the
whole question in one line. Breadcrumbs now also mark entering wails.Run,
reaching OnStartup, and the window painting — which places any launch
that produces nothing between two known points.
2026-08-25 21:07:47 +02:00

50 lines
1.7 KiB
Go

//go:build windows
package main
// Is the WebView2 runtime actually installed?
//
// It is the one dependency OpsLog cannot ship inside its own executable, and
// its absence is invisible: the process starts, Wails fails to create the
// browser environment, and on some machines that failure arrives as a silent
// exit rather than as an error we can print. So the version is read straight
// from where the runtime registers itself, and written to the startup log
// BEFORE the window is attempted — a log that says "WebView2: not found"
// answers the whole question in one line.
import (
"golang.org/x/sys/windows/registry"
)
// webview2Client is the runtime's own update-client GUID, the key it registers
// its version under. Documented by Microsoft for exactly this check.
const webview2Client = `Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}`
// webView2Version returns the installed runtime version, or "" if there is none.
//
// Both hives: a per-machine install writes to HKLM (and to the WOW6432 view of
// it on 64-bit Windows, which is where it usually lands), a per-user install to
// HKCU. Missing all three is the answer that matters.
func webView2Version() string {
type place struct {
key registry.Key
access uint32
}
for _, p := range []place{
{registry.CURRENT_USER, registry.QUERY_VALUE},
{registry.LOCAL_MACHINE, registry.QUERY_VALUE},
{registry.LOCAL_MACHINE, registry.QUERY_VALUE | registry.WOW64_32KEY},
} {
k, err := registry.OpenKey(p.key, webview2Client, p.access)
if err != nil {
continue
}
v, _, err := k.GetStringValue("pv")
k.Close()
if err == nil && v != "" && v != "0.0.0.0" {
return v
}
}
return ""
}