Skip to content

Commit 6c56239

Browse files
committed
Finish installer and uninstaller code for Windows, move vars around a bit (webserver port var initialized in vars, not sdkapp)
Former-commit-id: 02902de
1 parent a0ebb94 commit 6c56239

File tree

9 files changed

+150
-46
lines changed

9 files changed

+150
-46
lines changed

chipper/cmd/windows/main.go

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ import (
44
"fmt"
55
"os"
66
"os/exec"
7+
"path/filepath"
78
"runtime"
89
"strconv"
910

1011
"github.com/getlantern/systray"
1112
"github.com/kercre123/chipper/pkg/logger"
1213
"github.com/kercre123/chipper/pkg/vars"
13-
"github.com/kercre123/chipper/pkg/wirepod/sdkapp"
1414
botsetup "github.com/kercre123/chipper/pkg/wirepod/setup"
1515
stt "github.com/kercre123/chipper/pkg/wirepod/stt/vosk"
1616
"github.com/ncruces/zenity"
17+
"golang.org/x/sys/windows/registry"
1718
)
1819

1920
// this directory contains code which compiled a single program for end users. gui elements are implemented.
@@ -25,7 +26,7 @@ var mBoxSuccess = `Wire-pod has started successfully! It is now running in the b
2526
var mBoxIcon = "./icons/start-up-full.png"
2627

2728
func getNeedsSetupMsg() string {
28-
return `Wire-pod is now running in the background. You must set it up by heading to http://` + botsetup.GetOutboundIP().String() + `:` + sdkapp.WebPort + ` in a browser.`
29+
return `Wire-pod is now running in the background. You must set it up by heading to http://` + botsetup.GetOutboundIP().String() + `:` + vars.WebPort + ` in a browser.`
2930
}
3031

3132
func main() {
@@ -47,7 +48,23 @@ func main() {
4748
os.Exit(1)
4849
}
4950
}
50-
os.WriteFile(conf+"/runningPID", []byte(strconv.Itoa(os.Getpid())), 0777)
51+
os.WriteFile(conf+"\\runningPID", []byte(strconv.Itoa(os.Getpid())), 0777)
52+
os.WriteFile(filepath.Join(os.TempDir(), "/wirepodrunningPID"), []byte(strconv.Itoa(os.Getpid())), 0777)
53+
54+
keyPath := `Software\Microsoft\Windows\CurrentVersion\Uninstall\wire-pod`
55+
k, err := registry.OpenKey(registry.LOCAL_MACHINE, keyPath, registry.QUERY_VALUE)
56+
if err != nil {
57+
ErrMsg(fmt.Errorf("error opening key from the registry: " + err.Error()))
58+
}
59+
val, _, err := k.GetStringValue("InstallPath")
60+
if err != nil {
61+
ErrMsg(fmt.Errorf("error getting value from the registry: " + err.Error()))
62+
}
63+
err = os.Chdir(filepath.Join(val, "chipper"))
64+
fmt.Println("Working directory: " + val)
65+
if err != nil {
66+
ErrMsg(fmt.Errorf("error setting directory to " + val))
67+
}
5168
systray.Run(onReady, onExit)
5269
}
5370

@@ -94,7 +111,7 @@ func onReady() {
94111
)
95112
ExitProgram(0)
96113
case <-mBrowse.ClickedCh:
97-
go openBrowser("http://" + botsetup.GetOutboundIP().String() + ":" + sdkapp.WebPort)
114+
go openBrowser("http://" + botsetup.GetOutboundIP().String() + ":" + vars.WebPort)
98115
}
99116
}
100117
}()

chipper/cmd/windows/win-initwirepod.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"github.com/kercre123/chipper/pkg/vars"
2323
wpweb "github.com/kercre123/chipper/pkg/wirepod/config-ws"
2424
wp "github.com/kercre123/chipper/pkg/wirepod/preqs"
25-
"github.com/kercre123/chipper/pkg/wirepod/sdkapp"
2625
sdkWeb "github.com/kercre123/chipper/pkg/wirepod/sdkapp"
2726
botsetup "github.com/kercre123/chipper/pkg/wirepod/setup"
2827
"github.com/ncruces/zenity"
@@ -41,7 +40,7 @@ var voiceProcessor *wp.Server
4140

4241
var epodIsPosting bool
4342

44-
var NotSetUp string = "Wire-pod is not setup. Use the webserver at port " + sdkapp.WebPort + " to set up wire-pod."
43+
var NotSetUp string = "Wire-pod is not setup. Use the webserver at port " + vars.WebPort + " to set up wire-pod."
4544

4645
func NeedsSetupMsg() {
4746
go func() {
@@ -53,7 +52,7 @@ func NeedsSetupMsg() {
5352
)
5453
if err != nil {
5554
if err == zenity.ErrExtraButton {
56-
openBrowser("http://" + botsetup.GetOutboundIP().String() + ":" + sdkapp.WebPort)
55+
openBrowser("http://" + botsetup.GetOutboundIP().String() + ":" + vars.WebPort)
5756
}
5857
}
5958
}()
@@ -129,20 +128,20 @@ func BeginWirepodSpecific(sttInitFunc func() error, sttHandlerFunc interface{},
129128
func StartFromProgramInit(sttInitFunc func() error, sttHandlerFunc interface{}, voiceProcessorName string) {
130129
err := BeginWirepodSpecific(sttInitFunc, sttHandlerFunc, voiceProcessorName)
131130
if err != nil {
132-
logger.Println("Wire-pod is not setup. Use the webserver at port " + sdkapp.WebPort + " to set up wire-pod.")
131+
logger.Println("Wire-pod is not setup. Use the webserver at port " + vars.WebPort + " to set up wire-pod.")
133132
vars.APIConfig.PastInitialSetup = false
134133
vars.WriteConfigToDisk()
135134
NeedsSetupMsg()
136-
systray.SetTooltip("wire-pod must be set up at http://" + botsetup.GetOutboundIP().String() + ":" + sdkapp.WebPort)
135+
systray.SetTooltip("wire-pod must be set up at http://" + botsetup.GetOutboundIP().String() + ":" + vars.WebPort)
137136
} else if !vars.APIConfig.PastInitialSetup {
138-
logger.Println("Wire-pod is not setup. Use the webserver at port " + sdkapp.WebPort + " to set up wire-pod.")
137+
logger.Println("Wire-pod is not setup. Use the webserver at port " + vars.WebPort + " to set up wire-pod.")
139138
NeedsSetupMsg()
140-
systray.SetTooltip("wire-pod must be set up at http://" + botsetup.GetOutboundIP().String() + ":" + sdkapp.WebPort)
139+
systray.SetTooltip("wire-pod must be set up at http://" + botsetup.GetOutboundIP().String() + ":" + vars.WebPort)
141140
} else if vars.APIConfig.STT.Service == "vosk" && vars.APIConfig.STT.Language == "" {
142141
logger.Println("\033[33m\033[1mLanguage value is blank, but STT service is Vosk. Reinitiating setup process.\033[0m")
143-
logger.Println("Wire-pod is not setup. Use the webserver at port " + sdkapp.WebPort + " to set up wire-pod.")
142+
logger.Println("Wire-pod is not setup. Use the webserver at port " + vars.WebPort + " to set up wire-pod.")
144143
NeedsSetupMsg()
145-
systray.SetTooltip("wire-pod must be set up at http://" + botsetup.GetOutboundIP().String() + ":" + sdkapp.WebPort)
144+
systray.SetTooltip("wire-pod must be set up at http://" + botsetup.GetOutboundIP().String() + ":" + vars.WebPort)
146145
vars.APIConfig.PastInitialSetup = false
147146
} else {
148147
go StartChipper(true)

chipper/cmd/wire-pod-installer/install.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,18 @@ func InstallWirePod(is InstallSettings) error {
123123
UpdateInstallStatus("Updating registry...")
124124

125125
UpdateRegistry(is)
126+
if is.RunAtStartup {
127+
RunPodAtStartup(is)
128+
}
129+
126130
UpdateInstallBar(90)
127131

128132
UpdateInstallStatus("Creating shortcut...")
129133
CreateShortcut(is)
130134

135+
UpdateInstallStatus("Creating firewall rules...")
136+
AllowThroughFirewall(is)
137+
131138
UpdateInstallStatus("Done!")
132139

133140
UpdateInstallBar(100)

chipper/cmd/wire-pod-installer/main.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import (
44
"embed"
55
"fmt"
66
"os"
7+
"os/exec"
8+
"path/filepath"
79
"strconv"
810
"strings"
11+
"syscall"
912

1013
"fyne.io/fyne/v2"
1114
"fyne.io/fyne/v2/app"
@@ -20,6 +23,8 @@ var iconData embed.FS
2023

2124
var amd64podURL string = "https://github.com/kercre123/wire-pod/releases/latest/download/wire-pod-win-amd64.zip"
2225

26+
//var amd64podURL string = "http://192.168.1.2:82/wire-pod-win-amd64.zip"
27+
2328
var DefaultInstallationDirectory string = "C:\\Program Files\\wire-pod"
2429

2530
var icon *fyne.StaticResource
@@ -55,7 +60,14 @@ func GetStatusChan() chan string {
5560
return installerStatusUpdate
5661
}
5762

58-
func PostInstall(myApp fyne.App) {
63+
func ExecuteDetached(program string) error {
64+
cmd := exec.Command(program)
65+
// Start the program in a new process group to make it detached
66+
cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP}
67+
return cmd.Start()
68+
}
69+
70+
func PostInstall(myApp fyne.App, is InstallSettings) {
5971
var shouldStartPod bool = true
6072
window := myApp.NewWindow("wire-pod installer")
6173
window.Resize(fyne.Size{Width: 600, Height: 100})
@@ -74,7 +86,8 @@ func PostInstall(myApp fyne.App) {
7486

7587
exitButton := widget.NewButton("Exit", func() {
7688
if shouldStartPod {
77-
fmt.Println("Would start wire-pod here")
89+
window.Hide()
90+
ExecuteDetached(filepath.Join(is.Where, "chipper/chipper.exe"))
7891
}
7992
os.Exit(0)
8093
})
@@ -120,7 +133,7 @@ func DoInstall(myApp fyne.App, is InstallSettings) {
120133
}()
121134
InstallWirePod(is)
122135
window.Hide()
123-
PostInstall(myApp)
136+
PostInstall(myApp, is)
124137
}
125138

126139
func GetPreferences(myApp fyne.App) {
@@ -129,12 +142,9 @@ func GetPreferences(myApp fyne.App) {
129142
window.SetIcon(icon)
130143
window.Resize(fyne.Size{Width: 600, Height: 200})
131144
window.CenterOnScreen()
132-
launchOnStartup := widget.NewCheck("Launch on startup?", func(checked bool) {
145+
launchOnStartup := widget.NewCheck("Automatically launch wire-pod after login?", func(checked bool) {
133146
is.RunAtStartup = checked
134147
})
135-
autoUpdate := widget.NewCheck("Auto-update?", func(checked bool) {
136-
is.AutoUpdate = checked
137-
})
138148

139149
installDir := widget.NewEntry()
140150
installDir.SetText(DefaultInstallationDirectory)
@@ -168,7 +178,6 @@ func GetPreferences(myApp fyne.App) {
168178
Text: "This program will install wire-pod with the following settings.",
169179
}),
170180
launchOnStartup,
171-
autoUpdate,
172181
widget.NewSeparator(),
173182
widget.NewRichText(&widget.TextSegment{
174183
Text: "Installation Directory",
@@ -199,6 +208,9 @@ func StopWirePodIfRunning() {
199208
}
200209

201210
func ValidateInstallDirectory(dir string) bool {
211+
if dir == "C:\\Program Files" || dir == "C:\\Program Files\\" {
212+
return false
213+
}
202214
var dirWithoutLast string
203215
splitDir := strings.Split(dir, "\\")
204216
dirWithoutLast = splitDir[0]

chipper/cmd/wire-pod-installer/registry.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package main
22

33
import (
44
"fmt"
5+
"log"
6+
"os/exec"
57
"path/filepath"
68

79
"golang.org/x/sys/windows/registry"
@@ -35,5 +37,43 @@ func UpdateRegistry(is InstallSettings) {
3537
k.SetStringValue("Publisher", publisher)
3638
k.SetStringValue("UninstallString", uninstallString)
3739
k.SetStringValue("InstallLocation", installLocation)
40+
k.SetStringValue("InstallPath", is.Where)
3841
fmt.Println("Registry entries successfully created")
3942
}
43+
44+
func RunPodAtStartup(is InstallSettings) {
45+
key, _ := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.SET_VALUE)
46+
key.SetStringValue("wire-pod", filepath.Join(is.Where, "\\chipper\\chipper.exe"))
47+
}
48+
49+
func AllowThroughFirewall(is InstallSettings) {
50+
cmdStr := fmt.Sprintf("netsh advfirewall firewall add rule name=\"wire-pod\" dir=in action=allow program=\"%s\\chipper\\chipper.exe\" enable=yes", is.Where)
51+
fmt.Println("Executing command:", cmdStr)
52+
cmd := exec.Command("netsh", "advfirewall", "firewall", "add", "rule",
53+
"name=wire-pod",
54+
"dir=in",
55+
"action=allow",
56+
"profile=any",
57+
"program="+is.Where+"\\chipper\\chipper.exe",
58+
"enable=yes")
59+
60+
out, err := cmd.Output()
61+
if err != nil {
62+
fmt.Println(string(out))
63+
log.Fatalf("Failed to execute command in: %s", err)
64+
}
65+
cmd = exec.Command("netsh", "advfirewall", "firewall", "add", "rule",
66+
"name=wire-pod",
67+
"dir=out",
68+
"action=allow",
69+
"profile=any",
70+
"program="+is.Where+"\\chipper\\chipper.exe",
71+
"enable=yes")
72+
73+
err = cmd.Run()
74+
if err != nil {
75+
log.Fatalf("Failed to execute command out: %s", err)
76+
}
77+
78+
log.Println("Firewall rule added successfully.")
79+
}

chipper/cmd/wire-pod-installer/uninstall/main.go

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ import (
1111
)
1212

1313
func StopWirePodIfRunning() {
14-
confDir, _ := os.UserConfigDir()
15-
podDir := confDir + "/wire-pod"
16-
podPid, err := os.ReadFile(podDir + "/runningPID")
14+
podPid, err := os.ReadFile(filepath.Join(os.TempDir(), "/wirepodrunningPID"))
1715
if err == nil {
1816
pid, _ := strconv.Atoi(string(podPid))
1917
// doesn't work on unix, but should on Windows
@@ -29,15 +27,46 @@ func StopWirePodIfRunning() {
2927

3028
func main() {
3129
StopWirePodIfRunning()
32-
wd, _ := os.Getwd()
33-
os.RemoveAll(filepath.Join(wd, "chipper"))
34-
os.RemoveAll(filepath.Join(wd, "vector-cloud"))
30+
err := zenity.Question(
31+
"Would you like to remove application data, like saved bot settings or API preferences?",
32+
zenity.ExtraButton("No"),
33+
)
34+
if err == nil {
35+
conf, _ := os.UserConfigDir()
36+
os.RemoveAll(filepath.Join(conf, "wire-pod"))
37+
}
3538
keyPath := `Software\Microsoft\Windows\CurrentVersion\Uninstall\wire-pod`
39+
k, err := registry.OpenKey(registry.LOCAL_MACHINE, keyPath, registry.QUERY_VALUE)
40+
if err != nil {
41+
fmt.Println(err)
42+
return
43+
}
44+
val, _, err := k.GetStringValue("InstallPath")
45+
if err != nil {
46+
fmt.Println(err)
47+
return
48+
}
49+
50+
k.Close()
3651
registry.DeleteKey(registry.LOCAL_MACHINE, keyPath)
52+
53+
DontRunPodAtStartup()
54+
55+
fmt.Println(val)
56+
57+
os.RemoveAll(filepath.Join(val, "chipper"))
58+
os.RemoveAll(filepath.Join(val, "vector-cloud"))
59+
os.Remove("C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\wire-pod.lnk")
3760
zenity.Info(
38-
"wire-pod has been successfully uninstalled.",
61+
"wire-pod has successfully been uninstalled.",
3962
zenity.InfoIcon,
4063
zenity.Title("wire-pod uninstaller"),
4164
)
65+
os.RemoveAll(val)
4266
os.Exit(0)
4367
}
68+
69+
func DontRunPodAtStartup() {
70+
key, _ := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Run`, registry.SET_VALUE)
71+
key.DeleteValue("wire-pod")
72+
}

chipper/pkg/vars/vars.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ var (
3939
Certs = "../certs"
4040
)
4141

42+
var WebPort string = "8080"
43+
4244
// /home/name/.anki_vector/
4345
var SDKIniPath string
4446
var BotJdocs []botjdoc
@@ -136,6 +138,17 @@ func Init() {
136138
os.Mkdir(Certs, 0777)
137139
}
138140

141+
if os.Getenv("WEBSERVER_PORT") != "" {
142+
if _, err := strconv.Atoi(os.Getenv("WEBSERVER_PORT")); err == nil {
143+
WebPort = os.Getenv("WEBSERVER_PORT")
144+
} else {
145+
logger.Println("WEBSERVER_PORT contains letters, using default of 8080")
146+
WebPort = "8080"
147+
}
148+
} else {
149+
WebPort = "8080"
150+
}
151+
139152
// figure out user SDK path, containing sdk_config.ini
140153
// has to be done like this because wire-pod is running as root
141154
// path should be /home/name/wire-pod/chipper

chipper/pkg/wirepod/config-ws/webserver.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/kercre123/chipper/pkg/vars"
1313
"github.com/kercre123/chipper/pkg/wirepod/localization"
1414
processreqs "github.com/kercre123/chipper/pkg/wirepod/preqs"
15-
"github.com/kercre123/chipper/pkg/wirepod/sdkapp"
1615
botsetup "github.com/kercre123/chipper/pkg/wirepod/setup"
1716
"github.com/ncruces/zenity"
1817
)
@@ -333,12 +332,12 @@ func StartWebServer() {
333332
http.HandleFunc("/session-certs/", certHandler)
334333
webRoot := http.FileServer(http.Dir("./webroot"))
335334
http.Handle("/", webRoot)
336-
fmt.Printf("Starting webserver at port " + sdkapp.WebPort + " (http://localhost:" + sdkapp.WebPort + ")\n")
337-
if err := http.ListenAndServe(":"+sdkapp.WebPort, nil); err != nil {
338-
logger.Println("Error binding to " + sdkapp.WebPort + ": " + err.Error())
335+
fmt.Printf("Starting webserver at port " + vars.WebPort + " (http://localhost:" + vars.WebPort + ")\n")
336+
if err := http.ListenAndServe(":"+vars.WebPort, nil); err != nil {
337+
logger.Println("Error binding to " + vars.WebPort + ": " + err.Error())
339338
if vars.Packaged {
340339
zenity.Error(
341-
"FATAL: Wire-pod was unable to bind to port "+sdkapp.WebPort+". Another process is likely using it. Exiting.",
340+
"FATAL: Wire-pod was unable to bind to port "+vars.WebPort+". Another process is likely using it. Exiting.",
342341
zenity.ErrorIcon,
343342
zenity.Title("wire-pod"),
344343
)

0 commit comments

Comments
 (0)