open_at_login 0.0.1 copy "open_at_login: ^0.0.1" to clipboard
open_at_login: ^0.0.1 copied to clipboard

A Flutter package to enable or disable launching desktop applications (macOS and Windows) automatically at user login.

open_at_login #

A Flutter package for controlling whether desktop Flutter applications (macOS and Windows) launch automatically when the user logs in.

open_at_login provides a unified, production-ready Flutter API to query, enable, and disable launch-at-login behavior on:

  • macOS: Apple's modern Service Management login-item APIs via LaunchAtLogin-Modern (SMAppService.mainApp).
  • Windows: Both unpackaged Win32 applications (via HKCU\Software\Microsoft\Windows\CurrentVersion\Run) and MSIX packaged applications (via Windows.ApplicationModel.StartupTask), automatically detected and routed at runtime.

Features #

  • Unified desktop API: Identical public Dart API across macOS and Windows.
  • Check status: Inspect whether the application is currently registered to launch at login.
  • Enable launch at login: Register the application to start automatically upon user login.
  • Disable launch at login: Unregister the application from launching at login.
  • Modern macOS integration: Uses Apple's modern macOS 13+ login-item mechanism (SMAppService.mainApp).
  • Dual Windows support: Transparently handles both standalone unpackaged Win32 .exe and MSIX packaged distributions.
  • Graceful no-op on other platforms: Mobile, Linux, and Web safely no-op without requiring consumer platform checks.
  • Clean Flutter architecture: Singleton interface communicating over a standard Flutter MethodChannel.

Platform Support:

  • macOS: Fully supported via LaunchAtLogin-Modern (SMAppService.mainApp, macOS 13+).
  • Windows: Fully supported for both unpackaged EXE (via HKCU\Software\Microsoft\Windows\CurrentVersion\Run) and MSIX packaged applications (via Windows.ApplicationModel.StartupTask). Automatic runtime package detection and internal routing.
  • Other platforms (Linux, Android, iOS, Web): Safely handled as graceful no-ops (isEnabled() returns false, setEnabled(...) does nothing). Consumers do not need platform guards.

Requirements #

  • Flutter SDK: >=1.17.0
  • Dart SDK: ^3.13.2
  • macOS Deployment Target: macOS 13.0 or later
  • Windows Deployment Target: Windows 10 (1809+) or Windows 11

Installation #

Local / Path Dependency (Monorepo or In-Development) #

Add open_at_login as a path dependency in your application's pubspec.yaml:

dependencies:
  open_at_login:
    path: ../packages/open_at_login

Pub.dev Dependency (When Published) #

When published to pub.flutter-io.cn, add the package directly:

dependencies:
  open_at_login: ^0.0.1

Then fetch dependencies:

flutter pub get

macOS Native Setup #

open_at_login communicates with macOS through the native Swift package LaunchAtLogin-Modern. Because this is a native Swift Package Manager (SPM) dependency, you must add it once to your macOS Xcode project.

Follow these three steps in Xcode:

Step 1 — Add Package Dependencies #

  1. Open your Flutter project's macos folder in Xcode (or open macos/Runner.xcworkspace).

  2. From the Xcode menu bar, select:

    File → Add Package Dependencies...

Add Package Dependencies

Step 2 — Enter LaunchAtLogin-Modern URL #

In the search or repository URL field in the top-right corner of the dialog, enter:

https://github.com/sindresorhus/LaunchAtLogin-Modern

LaunchAtLogin-Modern

Step 3 — Select Runner Target #

When prompted to select package products and targets:

  1. Select the LaunchAtLogin product.
  2. Ensure it is added to the Runner target of your application.
  3. Click Add Package.

Select Runner Target


AppDelegate Setup #

Your macOS Flutter application's AppDelegate.swift connects the Flutter package API to the native LaunchAtLogin implementation via a Flutter MethodChannel.

Open macos/Runner/AppDelegate.swift in your project and configure it as shown below:

import Cocoa
import FlutterMacOS
import LaunchAtLogin

@main
class AppDelegate: FlutterAppDelegate {

  override func applicationDidFinishLaunching(_ notification: Notification) {
    guard let controller = mainFlutterWindow?.contentViewController as? FlutterViewController else {
      return
    }

    // Set up the MethodChannel for open_at_login
    let channel = FlutterMethodChannel(
      name: "open_at_login",
      binaryMessenger: controller.engine.binaryMessenger
    )

    channel.setMethodCallHandler { call, result in
      switch call.method {
      case "isOpenAtLoginEnabled":
        // Queries whether launch-at-login is currently enabled
        result(LaunchAtLogin.isEnabled)

      case "setOpenAtLoginEnabled":
        // Enables or disables launch-at-login
        guard let arguments = call.arguments as? [String: Any],
              let enabled = arguments["enabled"] as? Bool else {
          result(
            FlutterError(
              code: "INVALID_ARGUMENT",
              message: "Expected 'enabled' as a Boolean.",
              details: nil
            )
          )
          return
        }

        LaunchAtLogin.isEnabled = enabled
        result(nil)

      default:
        result(FlutterMethodNotImplemented)
      }
    }

    super.applicationDidFinishLaunching(notification)
  }

  override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
    return true
  }

  override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
    return true
  }
}

MethodChannel Specification #

  • Channel Name: open_at_login
  • Method isOpenAtLoginEnabled:
    • Invoked by OpenAtLogin.instance.isEnabled().
    • Returns Bool representing LaunchAtLogin.isEnabled.
  • Method setOpenAtLoginEnabled:
    • Invoked by OpenAtLogin.instance.setEnabled(bool).
    • Accepts argument dictionary {"enabled": bool}.
    • Updates LaunchAtLogin.isEnabled = enabled.

Windows Native Integration #

On Windows, open_at_login operates as a standard Flutter native C++ plugin that supports both unpackaged desktop executables and MSIX packaged applications. The plugin automatically detects the execution environment at runtime using GetCurrentPackageFamilyName and selects the appropriate native backend:

1. Unpackaged Applications (Win32 Registry Run Key) #

For standard standalone .exe distributions:

  • Registry Key: Interacts with the current user's startup registry key:

    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
    
  • Privileges: Runs purely in user mode (HKCU). No administrator rights or UAC elevation prompts are required.

  • Command Line Escaping: Automatically quotes executable paths and formats command line arguments according to Microsoft's standard CommandLineToArgvW escaping rules.

2. MSIX Packaged Applications (Windows.ApplicationModel.StartupTask) #

For applications packaged and distributed as MSIX:

  • API Mechanism: Uses the Windows Runtime Windows.ApplicationModel.StartupTask API.

  • Manifest Declaration: The package manifest (AppxManifest.xml) must declare a windows.startupTask extension:

    <Package ...
      xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
      xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
      IgnorableNamespaces="... desktop uap10">
      ...
      <Applications>
        <Application Id="App" Executable="YourApp.exe" EntryPoint="Windows.FullTrustApplication">
          <Extensions>
            <desktop:Extension Category="windows.startupTask" uap10:Parameters="--background">
              <desktop:StartupTask TaskId="AtFixStartupTask"
                                   Enabled="true"
                                   DisplayName="AtFix" />
            </desktop:Extension>
          </Extensions>
        </Application>
      </Applications>
    </Package>
    
  • TaskId Matching: The plugin automatically resolves candidate Task IDs based on the appName passed to initialize():

    • Exact appName (e.g. AtFix)
    • appName + "StartupTask" (e.g. AtFixStartupTask)
    • Sanitized alphanumeric variants (e.g. MyApp or MyAppStartupTask for My App)
  • Startup Arguments (--background):

    • In Windows 10 (2004+) and Windows 11, pass arguments via the uap10:Parameters attribute on the startup task <desktop:Extension>.
    • When using the msix Flutter packaging tool (pub.flutter-io.cn/packages/msix), configure startup_task: parameters: --background in your pubspec.yaml.
    • At runtime, packaged applications can also detect startup task activation by inspecting AppInstance.GetActivatedEventArgs().Kind == ActivationKind.StartupTask.
  • User Settings Policy: If the user has disabled the application's startup task in Windows Settings (Settings > Apps > Startup) or Task Manager, Windows policy prevents applications from programmatically overriding the setting. The plugin detects DisabledByUser and throws a descriptive PlatformException informing the user.


Usage #

1. Import the Package #

import 'package:open_at_login/open_at_login.dart';

2. Initialize the Instance #

Call initialize before interacting with the launch-at-login API:

final openAtLogin = OpenAtLogin.instance;

openAtLogin.initialize(
  appName: 'My App',
  appPath: '/Applications/My App.app',
);

3. Check Current Status #

final bool isEnabled = await openAtLogin.isEnabled();
print('Launch at login enabled: $isEnabled');

4. Enable or Disable Launch at Login #

// Enable launch at login
await openAtLogin.setEnabled(true);

// Disable launch at login
await openAtLogin.setEnabled(false);

Complete Example #

import 'package:flutter/material.dart';
import 'package:open_at_login/open_at_login.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  final openAtLogin = OpenAtLogin.instance;
  openAtLogin.initialize(
    appName: 'My App',
    appPath: '/Applications/My App.app',
  );

  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _openAtLogin = OpenAtLogin.instance;
  bool _isEnabled = false;
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _checkStatus();
  }

  Future<void> _checkStatus() async {
    final status = await _openAtLogin.isEnabled();
    setState(() {
      _isEnabled = status;
      _isLoading = false;
    });
  }

  Future<void> _toggle(bool value) async {
    setState(() => _isLoading = true);
    await _openAtLogin.setEnabled(value);
    await _checkStatus();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('OpenAtLogin Demo')),
        body: Center(
          child: _isLoading
              ? const CircularProgressIndicator()
              : SwitchListTile(
                  title: const Text('Launch at Login'),
                  value: _isEnabled,
                  onChanged: (val) => _toggle(val),
                ),
        ),
      ),
    );
  }
}

API Reference #

OpenAtLogin.instance #

static final OpenAtLogin instance

The global singleton accessor for the OpenAtLogin manager.

OpenAtLogin.initialize #

void initialize({
  required String appName,
  required String appPath,
  List<String> args = const [],
})
  • Purpose: Prepares the platform implementation. Should be called once during app startup.
  • Parameters:
    • appName: Display name of the application.
    • appPath: Executable or bundle path of the application.
    • args: Optional arguments list passed when launched at login.
  • Return Type: void
  • Behavior: On macOS, initializes the macOS launcher implementation. On Windows, initializes the Windows launcher slot. On other platforms, safely no-ops without throwing exceptions.

OpenAtLogin.isEnabled #

Future<bool> isEnabled()
  • Purpose: Checks whether the application is currently registered to launch at login.
  • Parameters: None.
  • Return Type: Future<bool>
  • Behavior: Returns true if enabled, false otherwise. Returns false safely on unsupported platforms or if called prior to initialize(). Propagates PlatformException if a supported platform encounters a native failure.

OpenAtLogin.setEnabled #

Future<void> setEnabled(bool enabled)
  • Purpose: Enables or disables launch at login.
  • Parameters:
    • enabled: true to register the application at login, false to unregister.
  • Return Type: Future<void>
  • Behavior: Sets the launch at login state on supported platforms. Safely no-ops on unsupported platforms or if called prior to initialize(). Propagates PlatformException if a supported platform encounters a native failure.

Important macOS Note #

LaunchAtLogin-Modern is a native Swift package dependency that communicates with macOS Service Management. The architecture follows this pipeline:

Flutter package (open_at_login)
    ↓
MethodChannel ("open_at_login")
    ↓
AppDelegate.swift
    ↓
LaunchAtLogin (Swift Package)
    ↓
macOS Login Items (SMAppService.mainApp)

Because open_at_login communicates across this channel, the native Swift Package Manager dependency must be added directly to the consuming application's Runner target in Xcode.


macOS Version Compatibility #

  • Supported: macOS 13.0 or later

LaunchAtLogin-Modern utilizes Apple's modern SMAppService.mainApp API introduced in macOS 13 (Ventura). It is designed specifically for macOS 13+ and does not support macOS 12 or earlier.


Troubleshooting #

Launch at Login does not work #

Verify the following items:

  1. SPM Dependency Added: Confirm LaunchAtLogin-Modern (https://github.com/sindresorhus/LaunchAtLogin-Modern) is present under Package Dependencies in your Xcode project.
  2. Target Assignment: Confirm LaunchAtLogin is linked against the Runner target in Xcode (Runner target → General → Frameworks, Libraries, and Embedded Content).
  3. AppDelegate Imports: Ensure import LaunchAtLogin is present at the top of macos/Runner/AppDelegate.swift.
  4. Channel Name: Verify the MethodChannel identifier in AppDelegate.swift is exactly "open_at_login".
  5. Method Names: Ensure the handled methods match "isOpenAtLoginEnabled" and "setOpenAtLoginEnabled".
  6. macOS Version: Verify the Mac running the application is on macOS 13.0 or later.

Example Project #

A complete working example application is provided in the repository:

packages/open_at_login/example

It demonstrates initialization, status checking, and toggling the launch-at-login state within a Flutter macOS application.


License & Repository #

  • Repository: GitHub
  • License: Released under the MIT License. Copyright (c) 2026 Pavan Kalyan.
1
likes
160
points
78
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter package to enable or disable launching desktop applications (macOS and Windows) automatically at user login.

Repository (GitHub)
View/report issues
Contributing

Topics

#macos #windows #launch-at-login #startup #desktop

License

MIT (license)

Dependencies

flutter

More

Packages that depend on open_at_login

Packages that implement open_at_login