1//go:build windows 2// +build windows 3 4package setup 5 6import ( 7 "fmt" 8 "golang.org/x/sys/windows/registry" 9 "os" 10 "os/exec" 11 "strings" 12) 13 14// https://stackoverflow.com/a/3964401 15func Install() error { 16 var ( 17 err error 18 keyRoot registry.Key 19 keyOpener registry.Key 20 ) 21 22 keyRoot, _, err = registry.CreateKey(registry.CLASSES_ROOT, PROTOCOL, registry.ALL_ACCESS) 23 if err != nil { 24 // if system wide install fails, use current user's registry 25 keypath := fmt.Sprintf("Software\\Classes\\%s", PROTOCOL) 26 keyRoot, _, err = registry.CreateKey(registry.CURRENT_USER, keypath, registry.ALL_ACCESS) 27 if err != nil { 28 return fmt.Errorf("failed to create root key. %s", err.Error()) 29 } 30 } 31 32 err = keyRoot.SetStringValue("", fmt.Sprintf("URL:%s Protocol", PROTOCOL)) 33 if err != nil { 34 return err 35 } 36 37 err = keyRoot.SetStringValue("URL Protocol", "") 38 if err != nil { 39 return err 40 } 41 42 keyOpener, _, err = registry.CreateKey(keyRoot, "shell\\open\\command", registry.ALL_ACCESS) 43 if err != nil { 44 return err 45 } 46 47 err = keyOpener.SetStringValue("", fmt.Sprintf("\"%s\" \"%%1\"", os.Args[0])) 48 if err != nil { 49 return err 50 } 51 52 return nil 53} 54 55func Uninstall() error { 56 var ( 57 err error 58 ) 59 60 // try system wide key first 61 _ = registry.DeleteKey(registry.CLASSES_ROOT, fmt.Sprintf("%s\\shell\\open\\command", PROTOCOL)) 62 _ = registry.DeleteKey(registry.CLASSES_ROOT, fmt.Sprintf("%s\\shell\\open", PROTOCOL)) 63 _ = registry.DeleteKey(registry.CLASSES_ROOT, fmt.Sprintf("%s\\shell", PROTOCOL)) 64 err = registry.DeleteKey(registry.CLASSES_ROOT, fmt.Sprintf("%s", PROTOCOL)) 65 if err == nil { 66 return nil 67 } 68 69 // still here? try user key 70 _ = registry.DeleteKey(registry.CURRENT_USER, fmt.Sprintf("Software\\Classes\\%s\\shell\\open\\command", PROTOCOL)) 71 _ = registry.DeleteKey(registry.CURRENT_USER, fmt.Sprintf("Software\\Classes\\%s\\shell\\open", PROTOCOL)) 72 _ = registry.DeleteKey(registry.CURRENT_USER, fmt.Sprintf("Software\\Classes\\%s\\shell", PROTOCOL)) 73 err = registry.DeleteKey(registry.CURRENT_USER, fmt.Sprintf("Software\\Classes\\%s", PROTOCOL)) 74 75 if err != nil { 76 return fmt.Errorf("Handler removal failed.\n%s", err.Error()) 77 } 78 79 return nil 80} 81 82func PreparePath(path string, isLetter bool) string { 83 return strings.Replace(path, "/", "\\", -1) 84} 85 86func Run(path string) error { 87 // note: the empty parameter is the title of the window and required even though it should be optional 88 out, err := exec.Command("cmd", "/C", "start", "", "/B", path).CombinedOutput() 89 90 if err != nil { 91 return fmt.Errorf("Failed to execute command.\n%s\n%s", err.Error(), out) 92 } 93 94 return nil 95} 96