Skip to content

Start At Login - #4474

Closed
leaanthony wants to merge 1 commit into
masterfrom
vk-d19d-implement
Closed

Start At Login#4474
leaanthony wants to merge 1 commit into
masterfrom
vk-d19d-implement

Conversation

@leaanthony

@leaanthony leaanthony commented Aug 4, 2025

Copy link
Copy Markdown
Member

Based off of https://github.com/wailsapp/wails/pull/3910/files

Summary by CodeRabbit

  • New Features

    • Added support for configuring applications to start automatically at user login on macOS, Windows, and Linux.
    • Introduced new options and methods to enable, disable, and check the "Start At Login" status across platforms.
    • Provided a comprehensive example and documentation demonstrating how to implement and use the "Start At Login" feature, including platform-specific instructions and troubleshooting tips.
  • Documentation

    • Added detailed README with usage examples, platform requirements, security considerations, and troubleshooting for the "Start At Login" feature.

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.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 4, 2025

Copy link
Copy Markdown

Deploying wails with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3f29158
Status: ✅  Deploy successful!
Preview URL: https://3db0e8e9.wails.pages.dev
Branch Preview URL: https://vk-d19d-implement.wails.pages.dev

View logs

@coderabbitai

coderabbitai Bot commented Aug 4, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This 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

Cohort / File(s) Change Summary
Documentation & Example
v3/examples/start-at-login/README.md, v3/examples/start-at-login/main.go
Added a new example application and detailed README demonstrating how to use the "Start At Login" feature in Wails v3, including code snippets, platform-specific notes, and troubleshooting guidance.
Core API & Options
v3/pkg/application/application.go, v3/pkg/application/application_options.go
Introduced public API methods to set and query autostart status; added StartAtLogin field to application options; integrated autostart logic into application startup sequence.
macOS Implementation
v3/pkg/application/application_darwin.go
Added Objective-C/cgo and Go methods to manage login items using AppleScript, enabling and querying autostart for macOS applications.
Linux Implementation
v3/pkg/application/application_linux.go
Implemented autostart management using .desktop files in the user's autostart directory, with helper methods for file creation, removal, and directory management.
Windows Implementation
v3/pkg/application/application_windows.go
Added methods to manage autostart via registry key manipulation under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run, including helpers for registry operations and executable path resolution.

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)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit hopped with code in sight,
To help your app start every night.
Mac, Linux, Windows—autostart’s a breeze,
With registry, scripts, and desktop keys.
Now your app can greet the dawn,
Hopping forward, never gone!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch vk-d19d-implement

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Aug 4, 2025
@github-actions github-actions Bot added Documentation Improvements or additions to documentation Windows MacOS Linux v3-alpha labels Aug 4, 2025
@leaanthony
leaanthony marked this pull request as draft August 4, 2025 11:05
@dosubot dosubot Bot added Enhancement New feature or request go Pull requests that update Go code labels Aug 4, 2025
@sonarqubecloud

sonarqubecloud Bot commented Aug 4, 2025

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between d863e52 and 3f29158.

📒 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.go
  • v3/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.go
  • v3/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.md
  • v3/examples/start-at-login/main.go
  • v3/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 StartAtLogin boolean 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 GreetService implementation 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 platformApp interface 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 SetStartAtLogin and StartsAtLogin methods 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 platformApp interface with descriptive error messages that provide helpful context for troubleshooting permissions and bundling issues.


282-282: LGTM! Necessary import addition.

The fmt import 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 setStartAtLogin method 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 startsAtLogin method 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 getAutostartDir method 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 removeDesktopFile method 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 setStartAtLogin method 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 startsAtLogin method 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 addToStartup method 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 removeFromStartup method handles the common case where the registry value doesn't exist by ignoring ERROR_FILE_NOT_FOUND, making it idempotent and safe to call multiple times.


475-507: Efficient registry query with proper error differentiation.

The isInStartup method uses RegQueryValueEx efficiently by:

  • Using KEY_QUERY_VALUE permission (minimal required access)
  • Passing nil for data buffer to only check existence
  • Properly distinguishing between "not found" (returns false) and actual errors

@ansxuman

Copy link
Copy Markdown
Contributor

Hi @leaanthony If anything is pending in this PR, let me know i can take it up.

@leaanthony
leaanthony changed the base branch from v3-alpha to master April 29, 2026 13:10
@taliesin-ai taliesin-ai added v3 and removed v3-alpha labels Aug 9, 2026
@leaanthony

Copy link
Copy Markdown
Member Author

Thanks for offering to help with this. The feature has since been implemented and merged in #5426 using the app.Autostart manager, including SMAppService/LaunchAgent support on macOS, Windows registry support, XDG autostart on Linux, identifiers, arguments, status reporting, and tests. That implementation supersedes this draft, so I’m closing it to avoid maintaining two competing approaches.

@leaanthony leaanthony closed this Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation Improvements or additions to documentation Enhancement New feature or request go Pull requests that update Go code Linux MacOS size:XL This PR changes 500-999 lines, ignoring generated files. v3 Windows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants