Init
This commit is contained in:
commit
d0187f94d7
23 changed files with 2489 additions and 0 deletions
147
spm/register_win.go
Normal file
147
spm/register_win.go
Normal file
|
@ -0,0 +1,147 @@
|
|||
// run_windows.go
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package spm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
// RegisterApp writes the necessary registry keys, making it appear as officially installed app
|
||||
func RegisterApp() error {
|
||||
exePath, err := GetInstallDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get install directory: %w", err)
|
||||
}
|
||||
|
||||
// 1. Create Uninstall/Modify entry
|
||||
uninstallKeyPath := `Software\Microsoft\Windows\CurrentVersion\Uninstall\SpitfireBrowser`
|
||||
uk, _, err := registry.CreateKey(registry.LOCAL_MACHINE, uninstallKeyPath, registry.ALL_ACCESS)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create uninstall key: %w", err)
|
||||
}
|
||||
defer uk.Close()
|
||||
|
||||
if err := uk.SetStringValue("DisplayName", "Spitfire"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := uk.SetStringValue("UninstallString", exePath+" --uninstall"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := uk.SetStringValue("ModifyPath", exePath+" --modify"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := uk.SetStringValue("DisplayIcon", exePath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. Register as a browser for default apps
|
||||
clientKeyPath := `Software\Clients\StartMenuInternet\SpitfireBrowser`
|
||||
ck, _, err := registry.CreateKey(registry.LOCAL_MACHINE, clientKeyPath, registry.ALL_ACCESS)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create client key: %w", err)
|
||||
}
|
||||
defer ck.Close()
|
||||
|
||||
if err := ck.SetStringValue("", "Spitfire"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create Capabilities subkey
|
||||
capabilitiesKeyPath := clientKeyPath + `\Capabilities`
|
||||
capk, _, err := registry.CreateKey(registry.LOCAL_MACHINE, capabilitiesKeyPath, registry.ALL_ACCESS)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create capabilities key: %w", err)
|
||||
}
|
||||
defer capk.Close()
|
||||
|
||||
if err := capk.SetStringValue("ApplicationName", "Spitfire"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := capk.SetStringValue("ApplicationDescription", "A custom browser"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set file associations
|
||||
assocKeyPath := capabilitiesKeyPath + `\FileAssociations`
|
||||
ak, _, err := registry.CreateKey(registry.LOCAL_MACHINE, assocKeyPath, registry.ALL_ACCESS)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create file associations key: %w", err)
|
||||
}
|
||||
defer ak.Close()
|
||||
|
||||
associations := map[string]string{
|
||||
".html": "SpitfireBrowserHTML",
|
||||
"HTTP": "SpitfireBrowserHTML",
|
||||
"HTTPS": "SpitfireBrowserHTML",
|
||||
}
|
||||
for ext, progID := range associations {
|
||||
if err := ak.SetStringValue(ext, progID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnregisterApp removes the registry entries created by registerApp.
|
||||
func UnregisterApp() error {
|
||||
// Remove the Uninstall/Modify entry.
|
||||
uninstallKeyPath := `Software\Microsoft\Windows\CurrentVersion\Uninstall\SpitfireBrowser`
|
||||
if err := deleteRegistryTree(registry.LOCAL_MACHINE, uninstallKeyPath); err != nil {
|
||||
return fmt.Errorf("failed to delete uninstall key: %w", err)
|
||||
}
|
||||
|
||||
// Remove the browser registration entry.
|
||||
clientKeyPath := `Software\Clients\StartMenuInternet\SpitfireBrowser`
|
||||
if err := deleteRegistryTree(registry.LOCAL_MACHINE, clientKeyPath); err != nil {
|
||||
return fmt.Errorf("failed to delete client key: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteRegistryTree recursively deletes a registry key and all its subkeys.
|
||||
func deleteRegistryTree(root registry.Key, path string) error {
|
||||
// Open the key with ALL_ACCESS permissions.
|
||||
key, err := registry.OpenKey(root, path, registry.ALL_ACCESS)
|
||||
if err != nil {
|
||||
// If the key does not exist, there's nothing to do.
|
||||
if err == registry.ErrNotExist {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
// Read the names of all subkeys.
|
||||
subKeys, err := key.ReadSubKeyNames(-1)
|
||||
key.Close() // Close the key so it can be deleted later.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Recursively delete each subkey.
|
||||
for _, subKey := range subKeys {
|
||||
subKeyPath := path + `\` + subKey
|
||||
if err := deleteRegistryTree(root, subKeyPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, delete the (now empty) key.
|
||||
return registry.DeleteKey(root, path)
|
||||
}
|
||||
|
||||
// IsRegistered returns true if the application is registered (installed) in the registry.
|
||||
func IsRegistered() bool {
|
||||
// Try to open the uninstall key with read-only access.
|
||||
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `Software\Microsoft\Windows\CurrentVersion\Uninstall\SpitfireBrowser`, registry.READ)
|
||||
if err != nil {
|
||||
// If the key cannot be opened, assume the app is not registered.
|
||||
return false
|
||||
}
|
||||
defer key.Close()
|
||||
return true
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue