From 9bb5f9b4ddcba4294cf31fc06833ef5c8099e891 Mon Sep 17 00:00:00 2001 From: Shablone <20610621+Shablone@users.noreply.github.com> Date: Tue, 2 Jun 2026 14:00:38 +0200 Subject: [PATCH] fix: on Windows don't allocate console if not opened inside one (#10726) This change allows Syncthing to be launched from Explorer without showing a console window, while preserving the existing command-line behavior. Previously, launching syncthing.exe from Explorer would always allocate a console window, which could only be hidden later by using `--no-console`. It was not possible to avoid console allocation entirely without introducing other issues. On Windows 24H2 and later a new application manifest allows us to achieve it. See [console allocation policy](https://learn.microsoft.com/en-us/windows/console/console-allocation-policy) This manifest is built into a syso-file by `goversioninfo`, which is already used to generate Windows resource files consumed by the Go compiler. **Note1:** On Windows 24H2 and later, no console is allocated when Syncthing is launched from Explorer, even if `--no-console` is set to `False`. It can still be used as a CLI tool as usual if you call it from console. **Note2:** The content of the manifest file may not be formatted. Even a `newline` would break it. ### Testing Tested on Windows 11 25H2: No console visible from explorer. CLI works as usual. Ref #8046, ref #10633, ref #10481, ref #10600 Signed-off-by: Elias <1elias.bauer@gmail.com> Co-authored-by: Elias <1elias.bauer@gmail.com> --- assets/windows/syncthing.exe.manifest | 8 ++++++++ build.go | 15 ++++++++++++--- cmd/syncthing/hideconsole_windows.go | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 assets/windows/syncthing.exe.manifest diff --git a/assets/windows/syncthing.exe.manifest b/assets/windows/syncthing.exe.manifest new file mode 100644 index 000000000..3757f2abc --- /dev/null +++ b/assets/windows/syncthing.exe.manifest @@ -0,0 +1,8 @@ + + + + + detached + + + \ No newline at end of file diff --git a/build.go b/build.go index 35c568d98..779b6a27e 100644 --- a/build.go +++ b/build.go @@ -732,9 +732,18 @@ func shouldBuildSyso(dir string) (string, error) { sysoPath := filepath.Join(dir, "cmd", "syncthing", "resource.syso") // See https://github.com/josephspurrier/goversioninfo#command-line-flags - arm := strings.HasPrefix(goarch, "arm") - a64 := strings.Contains(goarch, "64") - if _, err := runError("goversioninfo", "-o", sysoPath, fmt.Sprintf("-arm=%v", arm), fmt.Sprintf("-64=%v", a64)); err != nil { + // For manifest see https://learn.microsoft.com/en-us/windows/console/console-allocation-policy + isARM := strings.HasPrefix(goarch, "arm") + is64Bit := strings.Contains(goarch, "64") + + args := []string{ + "-manifest=assets/windows/syncthing.exe.manifest", // console-allocation-policy + "-o", sysoPath, // output path + fmt.Sprintf("-arm=%v", isARM), + fmt.Sprintf("-64=%v", is64Bit), + } + + if _, err := runError("goversioninfo", args...); err != nil { return "", errors.New("failed to create " + sysoPath + ": " + err.Error()) } diff --git a/cmd/syncthing/hideconsole_windows.go b/cmd/syncthing/hideconsole_windows.go index f51e8acc3..ef0848914 100644 --- a/cmd/syncthing/hideconsole_windows.go +++ b/cmd/syncthing/hideconsole_windows.go @@ -7,5 +7,5 @@ package main type buildSpecificOptions struct { - HideConsole bool `name:"no-console" help:"Hide console window" env:"STHIDECONSOLE"` + HideConsole bool `name:"no-console" help:"Hide console window (Always enabled on Windows 11 24H2 and later)" env:"STHIDECONSOLE"` }