1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Command winres writes the Windows resources of an executable (its icon,
// version information, and application manifest) as .syso objects that go
// build links into the package in the current folder: ./cmd/firefox-vpn-core,
// or with -program tun ./cmd/firefox-vpn-tun. scripts/build-windows.ps1 runs
// it before each build with the release version in APP_VERSION (else
// version.Current):
//
// APP_VERSION=1.1.0 go generate ./cmd/firefox-vpn-core ./cmd/firefox-vpn-tun
//
// The objects are build output, not kept in Git; a build without them has
// no icon, version information, or manifest.
package main
import (
"bytes"
"flag"
"fmt"
"os"
"github.com/tc-hib/winres"
winversion "github.com/tc-hib/winres/version"
"github.com/armanlife/firefox-vpn-client/core/internal/desktop"
"github.com/armanlife/firefox-vpn-client/core/internal/version"
)
// program is what each executable's version information says.
type program struct{ description, name string }
var programs = map[string]program{
"core": {"Firefox VPN Core", "firefox-vpn-core"},
// The administrator prompt shows this description when the app
// installs the service.
"tun": {"Firefox VPN TUN", "firefox-vpn-tun"},
}
func main() {
which := flag.String("program", "core", "the executable: core or tun")
flag.Parse()
p, ok := programs[*which]
if !ok {
fmt.Fprintln(os.Stderr, "winres: unknown program", *which)
os.Exit(2)
}
if err := run(p); err != nil {
fmt.Fprintln(os.Stderr, "winres:", err)
os.Exit(1)
}
}
func run(p program) error {
// The program's icon in every size, as app/tool/app_icons.py made it.
icon, err := winres.LoadICO(bytes.NewReader(desktop.AppIconICO))
if err != nil {
return err
}
var rs winres.ResourceSet
if err := rs.SetIcon(winres.Name("APP"), icon); err != nil {
return err
}
release := os.Getenv("APP_VERSION")
if release == "" {
release = version.Current
}
var vi winversion.Info
vi.SetFileVersion(release)
vi.SetProductVersion(release)
for key, value := range map[string]string{
winversion.ProductName: "Firefox VPN",
winversion.FileDescription: p.description,
winversion.OriginalFilename: p.name + ".exe",
winversion.InternalName: p.name,
// The publisher, as in the installer (AppPublisher) and the app.
winversion.CompanyName: "Arman",
winversion.LegalCopyright: "Copyright (c) 2026 Arman",
} {
if err := vi.Set(winversion.LangDefault, key, value); err != nil {
return err
}
}
rs.SetVersionInfo(vi)
// Runs with the user's rights (no elevation prompt: the TUN service's
// install asks for administrator rights itself, only then), declares
// Windows 10 and 11 like the app's manifest, and is per-monitor DPI
// aware for the tray icon and its menu.
rs.SetManifest(winres.AppManifest{
ExecutionLevel: winres.AsInvoker,
Compatibility: winres.Win10AndAbove,
DPIAwareness: winres.DPIPerMonitorV2,
})
for _, arch := range []winres.Arch{winres.ArchAMD64, winres.ArchARM64, winres.ArchI386} {
if err := writeObject(&rs, arch); err != nil {
return err
}
}
return nil
}
func writeObject(rs *winres.ResourceSet, arch winres.Arch) error {
f, err := os.Create("rsrc_windows_" + string(arch) + ".syso")
if err != nil {
return err
}
if err := rs.WriteObject(f, arch); err != nil {
f.Close()
return err
}
return f.Close()
}