mirror of https://github.com/Wox-launcher/Wox
feat(autostart): enhance autostart configuration handling on windows. fix #4231
* Improved logging for autostart setting mismatches. * Added functionality to attempt fixing autostart configuration when mismatches are detected. * Updated registry access methods for better clarity and error handling. * Introduced `setStartupApproved` and `removeStartupApproved` functions to manage startup approval status in Windows Settings.
This commit is contained in:
parent
7793308f27
commit
8c74c5cb63
|
@ -64,8 +64,25 @@ func (m *Manager) Init(ctx context.Context) error {
|
|||
} else {
|
||||
configAutostart := m.woxSetting.EnableAutostart.Get()
|
||||
if actualAutostart != configAutostart {
|
||||
util.GetLogger().Warn(ctx, fmt.Sprintf("Autostart setting mismatch: config %v, actual %v. Updating config.", configAutostart, actualAutostart))
|
||||
m.woxSetting.EnableAutostart.Set(actualAutostart)
|
||||
util.GetLogger().Warn(ctx, fmt.Sprintf("Autostart setting mismatch: config %v, actual %v", configAutostart, actualAutostart))
|
||||
|
||||
// If config says autostart should be enabled but actual is false,
|
||||
// try to re-enable autostart (this will fix broken autostart entries)
|
||||
if configAutostart && !actualAutostart {
|
||||
util.GetLogger().Info(ctx, "Attempting to fix autostart configuration...")
|
||||
fixErr := autostart.SetAutostart(ctx, true)
|
||||
if fixErr != nil {
|
||||
util.GetLogger().Error(ctx, fmt.Sprintf("Failed to fix autostart: %s", fixErr.Error()))
|
||||
// Update config to match actual state
|
||||
m.woxSetting.EnableAutostart.Set(false)
|
||||
} else {
|
||||
util.GetLogger().Info(ctx, "Autostart configuration fixed successfully")
|
||||
}
|
||||
} else {
|
||||
// Update config to match actual state
|
||||
m.woxSetting.EnableAutostart.Set(actualAutostart)
|
||||
}
|
||||
|
||||
err := m.SaveWoxSetting(ctx)
|
||||
if err != nil {
|
||||
util.GetLogger().Error(ctx, fmt.Sprintf("Failed to save updated autostart setting: %s", err.Error()))
|
||||
|
|
|
@ -8,15 +8,16 @@ import (
|
|||
)
|
||||
|
||||
func setAutostart(enable bool) error {
|
||||
key, _, err := registry.CreateKey(
|
||||
// Set the main Run registry entry
|
||||
runKey, _, err := registry.CreateKey(
|
||||
registry.CURRENT_USER,
|
||||
`Software\Microsoft\Windows\CurrentVersion\Run`,
|
||||
registry.ALL_ACCESS,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to access registry: %w", err)
|
||||
return fmt.Errorf("failed to access Run registry: %w", err)
|
||||
}
|
||||
defer key.Close()
|
||||
defer runKey.Close()
|
||||
|
||||
valueName := "WoxLauncher"
|
||||
|
||||
|
@ -25,14 +26,36 @@ func setAutostart(enable bool) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to get executable path: %w", err)
|
||||
}
|
||||
err = key.SetStringValue(valueName, exePath)
|
||||
|
||||
err = runKey.SetStringValue(valueName, exePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set registry value: %w", err)
|
||||
return fmt.Errorf("failed to set Run registry value: %w", err)
|
||||
}
|
||||
|
||||
// Verify the value was set correctly
|
||||
verifyValue, _, verifyErr := runKey.GetStringValue(valueName)
|
||||
if verifyErr != nil {
|
||||
return fmt.Errorf("failed to verify Run registry value: %w", verifyErr)
|
||||
}
|
||||
if verifyValue != exePath {
|
||||
return fmt.Errorf("Run registry value verification failed: expected %s, got %s", exePath, verifyValue)
|
||||
}
|
||||
|
||||
// Set the StartupApproved entry to enable the startup app in Windows Settings
|
||||
err = setStartupApproved(valueName, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set StartupApproved: %w", err)
|
||||
}
|
||||
} else {
|
||||
err = key.DeleteValue(valueName)
|
||||
err = runKey.DeleteValue(valueName)
|
||||
if err != nil && err != registry.ErrNotExist {
|
||||
return fmt.Errorf("failed to delete registry value: %w", err)
|
||||
return fmt.Errorf("failed to delete Run registry value: %w", err)
|
||||
}
|
||||
|
||||
// Remove the StartupApproved entry
|
||||
err = removeStartupApproved(valueName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to remove StartupApproved: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,24 +63,120 @@ func setAutostart(enable bool) error {
|
|||
}
|
||||
|
||||
func isAutostart() (bool, error) {
|
||||
key, _, err := registry.CreateKey(
|
||||
runKey, _, err := registry.CreateKey(
|
||||
registry.CURRENT_USER,
|
||||
`Software\Microsoft\Windows\CurrentVersion\Run`,
|
||||
registry.QUERY_VALUE,
|
||||
)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to access registry: %w", err)
|
||||
return false, fmt.Errorf("failed to access Run registry: %w", err)
|
||||
}
|
||||
defer key.Close()
|
||||
defer runKey.Close()
|
||||
|
||||
valueName := "WoxLauncher"
|
||||
_, _, err = key.GetStringValue(valueName)
|
||||
value, _, err := runKey.GetStringValue(valueName)
|
||||
if err == registry.ErrNotExist {
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to get registry value: %w", err)
|
||||
return false, fmt.Errorf("failed to get Run registry value: %w", err)
|
||||
}
|
||||
|
||||
// Check if the executable path still exists
|
||||
if _, statErr := os.Stat(value); os.IsNotExist(statErr) {
|
||||
// The registered executable doesn't exist, this means autostart is broken
|
||||
// We should return false so the system can detect and fix this
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Check StartupApproved status - if it exists and is disabled, return false
|
||||
approved, err := isStartupApproved(valueName)
|
||||
if err != nil {
|
||||
// If we can't read StartupApproved, assume it's enabled (backward compatibility)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return approved, nil
|
||||
}
|
||||
|
||||
// setStartupApproved sets the StartupApproved registry entry to enable/disable startup app in Windows Settings
|
||||
func setStartupApproved(valueName string, enabled bool) error {
|
||||
approvedKey, _, err := registry.CreateKey(
|
||||
registry.CURRENT_USER,
|
||||
`Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run`,
|
||||
registry.ALL_ACCESS,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to access StartupApproved registry: %w", err)
|
||||
}
|
||||
defer approvedKey.Close()
|
||||
|
||||
// The StartupApproved value is a binary value
|
||||
// Enabled: starts with 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
// Disabled: starts with 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
var binaryValue []byte
|
||||
if enabled {
|
||||
// Enabled state - first byte is 0x02
|
||||
binaryValue = []byte{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
} else {
|
||||
// Disabled state - first byte is 0x03
|
||||
binaryValue = []byte{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
}
|
||||
|
||||
err = approvedKey.SetBinaryValue(valueName, binaryValue)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set StartupApproved binary value: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// removeStartupApproved removes the StartupApproved registry entry
|
||||
func removeStartupApproved(valueName string) error {
|
||||
approvedKey, _, err := registry.CreateKey(
|
||||
registry.CURRENT_USER,
|
||||
`Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run`,
|
||||
registry.ALL_ACCESS,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to access StartupApproved registry: %w", err)
|
||||
}
|
||||
defer approvedKey.Close()
|
||||
|
||||
err = approvedKey.DeleteValue(valueName)
|
||||
if err != nil && err != registry.ErrNotExist {
|
||||
return fmt.Errorf("failed to delete StartupApproved value: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isStartupApproved checks if the startup app is approved (enabled) in Windows Settings
|
||||
func isStartupApproved(valueName string) (bool, error) {
|
||||
approvedKey, _, err := registry.CreateKey(
|
||||
registry.CURRENT_USER,
|
||||
`Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run`,
|
||||
registry.QUERY_VALUE,
|
||||
)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to access StartupApproved registry: %w", err)
|
||||
}
|
||||
defer approvedKey.Close()
|
||||
|
||||
binaryValue, _, err := approvedKey.GetBinaryValue(valueName)
|
||||
if err == registry.ErrNotExist {
|
||||
// If StartupApproved entry doesn't exist, assume it's enabled
|
||||
return true, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to get StartupApproved binary value: %w", err)
|
||||
}
|
||||
|
||||
// Check the first byte: 0x02 = enabled, 0x03 = disabled
|
||||
if len(binaryValue) > 0 {
|
||||
return binaryValue[0] == 0x02, nil
|
||||
}
|
||||
|
||||
// If binary value is empty, assume enabled
|
||||
return true, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue