Skip to content

Commit 6f82b11

Browse files
committed
Fix windows
1 parent 34ae6e9 commit 6f82b11

File tree

2 files changed

+73
-13
lines changed

2 files changed

+73
-13
lines changed

Makefile

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ clean:
44
-rm -rf ./output
55
-rm ./build/darwin/MultiMC-Twitch.app/Contents/MacOS/MultiMC-Twitch
66
-rm ./build/linux/usr/bin/multimc-twitch
7-
-rm ./build/windows/MultiMC-Twitch.exe
87

98
darwin:
109
mkdir -p output

main_windows.go

+73-12
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,136 @@
11
package main
22

33
import (
4-
"fmt"
54
"os"
5+
"path/filepath"
66

7+
"golang.org/x/sys/windows"
78
"golang.org/x/sys/windows/registry"
89
)
910

1011
func init() {
12+
ex, err := os.Executable()
13+
if err != nil {
14+
panic(err)
15+
}
16+
17+
exPath := filepath.Dir(ex)
18+
err = os.Chdir(exPath)
19+
if err != nil {
20+
panic(err)
21+
}
22+
23+
hasAdmin, err := CheckAdmin()
24+
if err != nil {
25+
panic(err)
26+
}
27+
28+
if hasAdmin {
29+
err = UpdateRegistry()
30+
if err != nil {
31+
panic(err)
32+
}
33+
}
34+
}
35+
36+
func UpdateRegistry() error {
1137
key, _, err := registry.CreateKey(registry.CLASSES_ROOT, "twitch", registry.WRITE)
1238
if err != nil {
13-
fmt.Println(err)
39+
return err
1440
}
1541

1642
defer key.Close()
1743

1844
err = key.SetStringValue("", "URL: Twitch Handler")
1945
if err != nil {
20-
fmt.Println(err)
46+
return err
2147
}
2248

2349
err = key.SetStringValue("URL Protocol", "")
2450
if err != nil {
25-
fmt.Println(err)
51+
return err
2652
}
2753

2854
iconKey, _, err := registry.CreateKey(key, "DefaultIcon", registry.WRITE)
2955
if err != nil {
30-
fmt.Println(err)
56+
return err
3157
}
3258

3359
defer iconKey.Close()
3460

3561
dir, err := os.Getwd()
3662
if err != nil {
37-
fmt.Println(err)
63+
return err
3864
}
3965

4066
err = iconKey.SetStringValue("", dir+"\\MultiMC.exe")
4167
if err != nil {
42-
fmt.Println(err)
68+
return err
4369
}
4470

4571
shellKey, _, err := registry.CreateKey(key, "shell", registry.WRITE)
4672
if err != nil {
47-
fmt.Println(err)
73+
return err
4874
}
4975

5076
defer shellKey.Close()
5177

5278
openKey, _, err := registry.CreateKey(shellKey, "open", registry.WRITE)
5379
if err != nil {
54-
fmt.Println(err)
80+
return err
5581
}
5682

5783
defer openKey.Close()
5884

5985
commandKey, _, err := registry.CreateKey(openKey, "command", registry.WRITE)
6086
if err != nil {
61-
fmt.Println(err)
87+
return err
6288
}
6389

6490
defer commandKey.Close()
6591

6692
executable, err := os.Executable()
6793
if err != nil {
68-
fmt.Println(err)
94+
return err
6995
}
7096

7197
err = commandKey.SetStringValue("", "\""+executable+"\" \"%1\"")
7298
if err != nil {
73-
fmt.Println(err)
99+
return err
100+
}
101+
102+
return nil
103+
}
104+
105+
// CheckAdmin determines if we have administrative privileges.
106+
// Ref: https://coolaj86.com/articles/golang-and-windows-and-admins-oh-my/
107+
func CheckAdmin() (bool, error) {
108+
var sid *windows.SID
109+
110+
// Although this looks scary, it is directly copied from the
111+
// official windows documentation. The Go API for this is a
112+
// direct wrap around the official C++ API.
113+
// See https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-checktokenmembership
114+
err := windows.AllocateAndInitializeSid(
115+
&windows.SECURITY_NT_AUTHORITY,
116+
2,
117+
windows.SECURITY_BUILTIN_DOMAIN_RID,
118+
windows.DOMAIN_ALIAS_RID_ADMINS,
119+
0, 0, 0, 0, 0, 0,
120+
&sid)
121+
if err != nil {
122+
return false, err
74123
}
124+
125+
// This appears to cast a null pointer so I'm not sure why this
126+
// works, but this guy says it does and it Works for Me™:
127+
// https://github.com/golang/go/issues/28804#issuecomment-438838144
128+
token := windows.Token(0)
129+
130+
member, err := token.IsMember(sid)
131+
if err != nil {
132+
return false, err
133+
}
134+
135+
return member, nil
75136
}

0 commit comments

Comments
 (0)