Skip to content

Commit c835cd0

Browse files
leaanthonyclaude
andcommitted
fix(windows): skip DPI awareness API call when already set via manifest
Check current DPI awareness before calling SetProcessDpiAwarenessContext. Windows only allows setting DPI awareness once per process - either via manifest or API, not both. If already set (e.g., via application manifest in built binaries), skip the API call to avoid "Access is denied" errors. Fixes #4803 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent bf1173c commit c835cd0

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

v3/UNRELEASED_CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ After processing, the content will be moved to the main changelog and this file
2020

2121
## Changed
2222
<!-- Changes in existing functionality -->
23+
- **BREAKING**: DPI awareness API calls are now skipped when already set via application manifest (#4803). Applications relying on the API call to override manifest settings will need to remove DPI settings from their manifest.
2324

2425
## Fixed
2526
<!-- Bug fixes -->
27+
- Fix SetProcessDpiAwarenessContext "Access is denied" error when DPI awareness is already set via application manifest (#4803)
2628

2729
## Deprecated
2830
<!-- Soon-to-be removed features -->

v3/pkg/application/application_windows.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,18 @@ func setupDPIAwareness() error {
358358
// https://learn.microsoft.com/en-us/windows/win32/hidpi/setting-the-default-dpi-awareness-for-a-process
359359
// https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
360360

361+
// Check if DPI awareness has already been set (e.g., via application manifest).
362+
// Windows only allows setting DPI awareness once per process - either via manifest
363+
// or API, not both. If already set, skip the API call to avoid "Access is denied" errors.
364+
// See: https://github.com/wailsapp/wails/issues/4803
365+
if w32.HasGetProcessDpiAwarenessFunc() {
366+
awareness, err := w32.GetProcessDpiAwareness()
367+
if err == nil && awareness != w32.PROCESS_DPI_UNAWARE {
368+
// DPI awareness already set (likely via manifest), skip API call
369+
return nil
370+
}
371+
}
372+
361373
if w32.HasSetProcessDpiAwarenessContextFunc() {
362374
// This is most recent version with the best results
363375
// supported beginning with Windows 10, version 1703

v3/pkg/w32/shcore.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,26 @@ var (
1212
modshcore = syscall.NewLazyDLL("shcore.dll")
1313

1414
procGetDpiForMonitor = modshcore.NewProc("GetDpiForMonitor")
15+
procGetProcessDpiAwareness = modshcore.NewProc("GetProcessDpiAwareness")
1516
procSetProcessDpiAwareness = modshcore.NewProc("SetProcessDpiAwareness")
1617
)
1718

19+
func HasGetProcessDpiAwarenessFunc() bool {
20+
err := procGetProcessDpiAwareness.Find()
21+
return err == nil
22+
}
23+
24+
// GetProcessDpiAwareness retrieves the DPI awareness of the current process.
25+
// Returns one of: PROCESS_DPI_UNAWARE, PROCESS_SYSTEM_DPI_AWARE, or PROCESS_PER_MONITOR_DPI_AWARE.
26+
func GetProcessDpiAwareness() (uint, error) {
27+
var awareness uint
28+
status, _, err := procGetProcessDpiAwareness.Call(0, uintptr(unsafe.Pointer(&awareness)))
29+
if status != S_OK {
30+
return 0, fmt.Errorf("GetProcessDpiAwareness failed: %v", err)
31+
}
32+
return awareness, nil
33+
}
34+
1835
func HasSetProcessDpiAwarenessFunc() bool {
1936
err := procSetProcessDpiAwareness.Find()
2037
return err == nil

0 commit comments

Comments
 (0)