Start At Login - #4474
Conversation
I have successfully implemented the "Start At Login" feature for Wails v3, addressing all the major concerns raised in PR #3910. Here's what was accomplished: ### ✅ **Core Implementation** 1. **Added StartAtLogin option** to `application.Options` struct 2. **Implemented platform-specific methods** for all three platforms: - **macOS**: Uses AppleScript with proper escaping to prevent injection attacks - **Windows**: Uses Windows Registry with restrictive permissions - **Linux**: Uses XDG autostart specification with .desktop files 3. **Added public API methods**: - `SetStartAtLogin(enabled bool) error` - Enable/disable start at login - `StartsAtLogin() (bool, error)` - Check current status ### ✅ **Security Improvements** (addressing PR comments) 1. **Path validation and sanitization** across all platforms 2. **AppleScript injection protection** on macOS with proper escaping 3. **Registry permissions** restricted to necessary access on Windows 4. **Executable path validation** with symlink resolution 5. **Input sanitization** for application names and paths ### ✅ **Error Handling & Documentation** 1. **Comprehensive error handling** with descriptive error messages 2. **Complete API documentation** with platform-specific behavior notes 3. **macOS Info.plist requirement** documented (NSAppleEventsUsageDescription) 4. **Cross-platform compatibility** notes and troubleshooting ### ✅ **Example & Testing** 1. **Working example application** demonstrating usage 2. **Comprehensive README** with platform-specific requirements 3. **Runtime toggling capability** implemented 4. **Compilation verified** - the implementation builds successfully ### 🔧 **Technical Details** - **macOS**: Uses Bundle information and AppleScript with security hardening - **Windows**: Uses HKEY_CURRENT_USER registry with KEY_SET_VALUE/KEY_QUERY_VALUE permissions - **Linux**: Creates XDG-compliant .desktop files in ~/.config/autostart/ ### 📋 **Key Features** - ✅ Cross-platform support (macOS, Windows, Linux) - ✅ Runtime configuration via public API - ✅ Application startup configuration via Options - ✅ Security hardening against injection attacks - ✅ Proper error handling and validation - ✅ Complete documentation and examples The implementation is now ready for testing and can be integrated into Wails v3. All major security concerns from the original PR have been addressed, and the feature includes proper documentation for developers.
Deploying wails with
|
| Latest commit: |
3f29158
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://3db0e8e9.wails.pages.dev |
| Branch Preview URL: | https://vk-d19d-implement.wails.pages.dev |
WalkthroughThis change introduces a cross-platform "Start At Login" feature for Wails v3 applications. It adds new API methods to enable, disable, and query autostart status on macOS, Windows, and Linux, with platform-specific implementations for each. Documentation and a new example application demonstrate usage and integration. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant App (Wails)
participant Platform (macOS/Windows/Linux)
User->>App (Wails): Launches Application
App (Wails)->>Platform: Check if StartAtLogin is enabled in options
alt StartAtLogin enabled
App (Wails)->>Platform: Enable Start At Login (platform-specific)
Platform-->>App (Wails): Success/Failure
end
User->>App (Wails): Toggle Start At Login via UI/API
App (Wails)->>Platform: setStartAtLogin(enabled)
Platform-->>App (Wails): Success/Failure
User->>App (Wails): Query Start At Login Status
App (Wails)->>Platform: startsAtLogin()
Platform-->>App (Wails): Status (true/false)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
v3/examples/start-at-login/README.md (2)
32-32: Fix trailing punctuation in heading.Remove the trailing colon to follow markdown style guidelines.
-### Enable Start At Login during application initialization: +### Enable Start At Login during application initialization
42-42: Fix trailing punctuation in heading.Remove the trailing colon to follow markdown style guidelines.
-### Toggle Start At Login at runtime: +### Toggle Start At Login at runtime
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
v3/examples/start-at-login/README.md(1 hunks)v3/examples/start-at-login/main.go(1 hunks)v3/pkg/application/application.go(3 hunks)v3/pkg/application/application_darwin.go(2 hunks)v3/pkg/application/application_linux.go(1 hunks)v3/pkg/application/application_options.go(1 hunks)v3/pkg/application/application_windows.go(2 hunks)
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: popaprozac
PR: wailsapp/wails#4230
File: v3/pkg/services/notifications/notifications_windows.go:132-136
Timestamp: 2025-04-22T22:47:26.436Z
Learning: The go-toast package in Wails handles COM initialization internally when using `SetAppData` and setting the activation callback in Windows notifications. Attempting to initialize COM again would result in an error indicating it's already initialized.
📚 Learning: in the notifications package, initialization of the `service` struct is handled through platform-spe...
Learnt from: popaprozac
PR: wailsapp/wails#4098
File: v3/pkg/services/notifications/notifications.go:46-55
Timestamp: 2025-03-24T20:22:56.233Z
Learning: In the notifications package, initialization of the `Service` struct is handled through platform-specific `New()` functions in each implementation file (darwin, windows, linux) rather than a generic constructor in the main package file. Each platform implementation follows a singleton pattern using `notificationServiceOnce.Do()` and creates a global `NotificationService` variable that's accessed through a thread-safe `getNotificationService()` function.
Applied to files:
v3/pkg/application/application_darwin.gov3/examples/start-at-login/main.go
📚 Learning: in the notifications package, initialization of the `service` struct is handled through platform-spe...
Learnt from: popaprozac
PR: wailsapp/wails#4098
File: v3/pkg/services/notifications/notifications.go:46-55
Timestamp: 2025-03-24T20:22:56.233Z
Learning: In the notifications package, initialization of the `Service` struct is handled through platform-specific `New()` functions in each implementation file (darwin, windows, linux) rather than a generic constructor in the main package file.
Applied to files:
v3/pkg/application/application_darwin.gov3/examples/start-at-login/main.go
📚 Learning: for the macos notifications implementation in wails, an early panic is used when the bundle identifi...
Learnt from: popaprozac
PR: wailsapp/wails#4098
File: v3/pkg/services/notifications/notifications_darwin.go:39-46
Timestamp: 2025-03-23T00:41:39.612Z
Learning: For the macOS notifications implementation in Wails, an early panic is used when the bundle identifier check fails rather than returning an error, because the Objective-C code would crash later anyway. The panic provides clear instructions to developers about bundling and signing requirements.
Applied to files:
v3/pkg/application/application_darwin.go
📚 Learning: in wails services (like ginservice), initializing the app field in servicestartup rather than in the...
Learnt from: leaanthony
PR: wailsapp/wails#4128
File: v3/examples/gin-service/services/gin_service.go:67-85
Timestamp: 2025-04-18T05:57:34.711Z
Learning: In Wails services (like GinService), initializing the app field in ServiceStartup rather than in the constructor is an acceptable pattern, as ServiceStartup is guaranteed to be called before any HTTP requests are handled.
Applied to files:
v3/examples/start-at-login/README.mdv3/examples/start-at-login/main.gov3/pkg/application/application_windows.go
📚 Learning: in wails v2, unlike v3-alpha which has a `serviceshutdown` method for services, there is no standard...
Learnt from: popaprozac
PR: wailsapp/wails#4256
File: v2/internal/frontend/desktop/linux/notifications.go:27-28
Timestamp: 2025-04-29T23:54:07.488Z
Learning: In Wails v2, unlike v3-alpha which has a `ServiceShutdown` method for services, there is no standardized teardown pattern for frontend implementations. When implementing features that require cleanup (like goroutines or resources), add explicit cleanup methods (e.g., `CleanupNotifications()`) that handle resource release, context cancellation, and connection closure.
Applied to files:
v3/examples/start-at-login/main.go
📚 Learning: in `v3/examples/window/main.go`, `time.sleep` is used within a goroutine and does not block the ui t...
Learnt from: leaanthony
PR: wailsapp/wails#3763
File: v3/examples/window/main.go:472-475
Timestamp: 2024-09-30T06:13:46.595Z
Learning: In `v3/examples/window/main.go`, `time.Sleep` is used within a goroutine and does not block the UI thread.
Applied to files:
v3/examples/start-at-login/main.go
📚 Learning: in wails applications, it's not necessary to implement explicit graceful shutdown for simple gorouti...
Learnt from: leaanthony
PR: wailsapp/wails#4234
File: v3/examples/badge-custom/main.go:87-93
Timestamp: 2025-04-26T21:03:42.481Z
Learning: In Wails applications, it's not necessary to implement explicit graceful shutdown for simple goroutines (like time emitters) as Go automatically terminates all goroutines as part of the application shutdown process.
Applied to files:
v3/examples/start-at-login/main.go
🧬 Code Graph Analysis (2)
v3/pkg/application/application_options.go (1)
v2/pkg/mac/login_darwin.go (1)
StartAtLogin(18-39)
v3/pkg/application/application_windows.go (1)
v3/pkg/w32/constants.go (5)
HKEY_CURRENT_USER(1872-1872)KEY_SET_VALUE(1887-1887)REG_SZ(2118-2118)ERROR_FILE_NOT_FOUND(17-17)KEY_QUERY_VALUE(1886-1886)
🪛 markdownlint-cli2 (0.17.2)
v3/examples/start-at-login/README.md
32-32: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
42-42: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: Run Go Tests v3 (windows-latest, 1.24)
- GitHub Check: Run Go Tests v3 (macos-latest, 1.24)
- GitHub Check: Run Go Tests v3 (ubuntu-latest, 1.24)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: semgrep/ci
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (20)
v3/pkg/application/application_options.go (1)
107-108: LGTM! Well-documented configuration option.The addition of the
StartAtLoginboolean field is properly documented and follows Go conventions. The placement at the end of the struct maintains backward compatibility.v3/examples/start-at-login/README.md (1)
1-99: Excellent comprehensive documentation.This README provides thorough coverage of the start-at-login feature, including platform-specific requirements, security considerations, and troubleshooting guidance. The code examples are clear and practical.
v3/examples/start-at-login/main.go (2)
10-40: LGTM! Well-implemented service methods.The
GreetServiceimplementation properly demonstrates the start-at-login feature with good error handling and appropriate return values for frontend consumption.
42-58: LGTM! Proper application setup demonstrating the feature.The main function correctly demonstrates how to configure the start-at-login feature and register the service. The commented StartAtLogin option allows users to test runtime toggling functionality.
v3/pkg/application/application.go (3)
202-203: LGTM! Appropriate interface extension.The new methods added to the
platformAppinterface follow Go conventions with proper error handling and clear naming.
595-600: LGTM! Appropriate non-fatal initialization.The start-at-login configuration during app initialization handles errors gracefully by logging warnings without preventing app startup, which is the correct behavior for this feature.
867-894: LGTM! Well-documented public API methods.The
SetStartAtLoginandStartsAtLoginmethods are properly implemented with comprehensive documentation, appropriate error handling, and platform delegation. The initialization checks prevent runtime errors.v3/pkg/application/application_darwin.go (3)
197-277: LGTM! Secure AppleScript implementation with proper protections.The C implementation properly handles AppleScript injection prevention through string escaping and includes appropriate memory management. The logic correctly uses bundle information and provides proper error handling.
Key security features:
- String escaping for both quotes and backslashes prevents injection
- Proper memory management with release calls
- Error checking on AppleScript execution
- Use of autorelease pools
380-393: LGTM! Appropriate Go wrappers with helpful error messages.The Go wrapper methods properly implement the
platformAppinterface with descriptive error messages that provide helpful context for troubleshooting permissions and bundling issues.
282-282: LGTM! Necessary import addition.The
fmtimport is required for the error formatting in the new start-at-login methods.v3/pkg/application/application_linux.go (5)
234-271: Solid implementation with proper path validation and XDG compliance.The
setStartAtLoginmethod correctly handles symbolic links, validates executable existence, and follows XDG autostart standards. The desktop filename sanitization prevents directory traversal attacks.
273-302: LGTM - Clean status check implementation.The
startsAtLoginmethod properly checks for desktop file existence and handles error cases appropriately. The logic is straightforward and correct.
304-323: Excellent XDG compliance and directory handling.The
getAutostartDirmethod correctly respects the XDG_CONFIG_HOME environment variable and creates the autostart directory with appropriate permissions (0755).
325-343: Desktop file format is correct and secure.The desktop file content follows the freedesktop.org specification with proper fields. File permissions (0644) are appropriate for desktop files.
345-356: Proper cleanup with idempotent behavior.The
removeDesktopFilemethod handles the case where the file doesn't exist gracefully, making it safe to call multiple times.v3/pkg/application/application_windows.go (5)
379-410: Secure implementation with proper key name validation.The
setStartAtLoginmethod includes excellent security measures:
- Validates executable existence and resolves symbolic links
- Sanitizes registry key names to prevent injection attacks with
strings.ContainsAny(keyName, "\\/:*?\"<>|")- Uses the executable name without extension as the registry key
412-424: Clean status check with proper error handling.The
startsAtLoginmethod correctly derives the registry key name and delegates to the helper method. Logic is sound and consistent with the setter method.
426-452: Proper registry operations with UTF-16 handling.The
addToStartupmethod correctly:
- Opens the registry key with minimal required permissions (KEY_SET_VALUE)
- Handles UTF-16 string conversion properly
- Calculates byte length correctly for UTF-16:
(len(exePath)+1)*2- Closes the registry key with defer
454-473: Robust removal with proper error handling.The
removeFromStartupmethod handles the common case where the registry value doesn't exist by ignoringERROR_FILE_NOT_FOUND, making it idempotent and safe to call multiple times.
475-507: Efficient registry query with proper error differentiation.The
isInStartupmethod usesRegQueryValueExefficiently by:
- Using
KEY_QUERY_VALUEpermission (minimal required access)- Passing
nilfor data buffer to only check existence- Properly distinguishing between "not found" (returns false) and actual errors
|
Hi @leaanthony If anything is pending in this PR, let me know i can take it up. |
|
Thanks for offering to help with this. The feature has since been implemented and merged in #5426 using the |



Based off of https://github.com/wailsapp/wails/pull/3910/files
Summary by CodeRabbit
New Features
Documentation