feat(upgrade): update correct registry entry

This commit is contained in:
Jan De Dobbeleer 2024-07-13 20:56:47 +02:00 committed by Jan De Dobbeleer
parent 58fd8e5f82
commit 62e782a4eb
4 changed files with 62 additions and 11 deletions

View file

@ -111,6 +111,7 @@ func (m *model) View() string {
m.spinner.Spinner = spinner.Moon
message = "Verifying download"
case installing:
m.spinner.Spinner = spinner.Jump
message = "Installing"
}

View file

@ -23,6 +23,8 @@ func install(tag string) error {
return err
}
setState(installing)
targetDir := filepath.Dir(executable)
fileName := filepath.Base(executable)
@ -68,7 +70,7 @@ func install(tag string) error {
_ = hideFile(oldPath)
}
updateRegistry(tag)
updateRegistry(tag, executable)
return nil
}

View file

@ -6,4 +6,4 @@ func hideFile(_ string) error {
return nil
}
func updateRegistry(_ string) {}
func updateRegistry(_, _ string) {}

View file

@ -1,6 +1,8 @@
package upgrade
import (
"errors"
"path/filepath"
"strconv"
"strings"
"syscall"
@ -27,9 +29,18 @@ func hideFile(path string) error {
return nil
}
func updateRegistry(version string) {
key, err := getRegistryKey()
func updateRegistry(version, executable string) {
// needs to be the parent directory of the executable's bin directory
// with a trailing backslash to match the registry key
// in case this wasn't installed with the installer, nothing will match
// and we don't set the registry keys
installLocation := filepath.Dir(executable)
installLocation = filepath.Dir(installLocation)
installLocation += `\`
key, err := getRegistryKey(installLocation)
if err != nil {
key.Close()
return
}
@ -40,6 +51,7 @@ func updateRegistry(version string) {
splitted := strings.Split(version, ".")
if len(splitted) < 3 {
key.Close()
return
}
@ -54,15 +66,51 @@ func updateRegistry(version string) {
_ = key.SetDWordValue("MinorVersion", minor)
_ = key.SetDWordValue("VersionMinor", minor)
}
key.Close()
}
func getRegistryKey() (registry.Key, error) {
path := `Software\Microsoft\Windows\CurrentVersion\Uninstall\Oh My Posh_is1`
// getRegistryKey tries all known registry paths to find the one we need to adjust (if any)
func getRegistryKey(installLocation string) (registry.Key, error) {
knownRegistryPaths := []struct {
Key registry.Key
Path string
}{
{registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Uninstall`},
{registry.CURRENT_USER, `Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall`},
{registry.LOCAL_MACHINE, `Software\Microsoft\Windows\CurrentVersion\Uninstall`},
{registry.LOCAL_MACHINE, `Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall`},
}
key, err := registry.OpenKey(registry.CURRENT_USER, path, registry.WRITE)
if err == nil {
for _, path := range knownRegistryPaths {
key, ok := tryRegistryKey(path.Key, path.Path, installLocation)
if ok {
return key, nil
}
return registry.OpenKey(registry.LOCAL_MACHINE, path, registry.WRITE)
}
return registry.CURRENT_USER, errors.New("could not find registry key")
}
// tryRegistryKey tries to open the registry key for the given path
// and checks if the install location matches with the current executable's location
func tryRegistryKey(key registry.Key, path, installLocation string) (registry.Key, bool) {
path += `\Oh My Posh_is1`
readKey, err := registry.OpenKey(key, path, registry.READ)
if err != nil {
return key, false
}
location, _, err := readKey.GetStringValue("InstallLocation")
if err != nil {
return key, false
}
if location != installLocation {
return key, false
}
key, err = registry.OpenKey(key, path, registry.WRITE)
return key, err == nil
}