using System.Runtime.InteropServices; using CursorLang.Core.Interop; using Windows.ApplicationModel; using Windows.ApplicationModel.Activation; namespace CursorLang.Core.Services; /// /// Whether Windows started the application by itself. /// /// /// A launch of its own accord ends up in the tray without a window: the user asked /// for the application to be there when they sign in, not for a window to greet them /// every morning. A launch by the user is another matter — the window is what they /// clicked for. /// /// The two builds tell the launches apart differently. A build in a folder is /// started from the registry, and the command written there carries an argument of /// its own — see . A package has no say in its command /// line, and Windows is asked about the activation instead. /// internal static class StartupLaunch { /// What the registry entry adds to the path of the application. internal const string Argument = "--startup"; /// Whether this launch is the doing of Windows rather than of the user. internal static bool IsAutomatic(IReadOnlyList arguments) => HasArgument(arguments) || IsStartupActivation(); /// The command line says the launch comes from the startup entry. internal static bool HasArgument(IReadOnlyList arguments) => arguments.Any(argument => string.Equals(argument, Argument, StringComparison.OrdinalIgnoreCase)); private static bool IsStartupActivation() { if (!PackageIdentityNative.IsPackaged) { return false; } try { return AppInstance.GetActivatedEventArgs() is { Kind: ActivationKind.StartupTask }; } catch (Exception e) when (e is COMException or InvalidOperationException or NotSupportedException) { // Windows has nothing to say about the activation. A window shown when it // was not asked for is a smaller mishap than an application that hides // when the user has just started it return false; } } }