From e1f44b817d32f339839b2c0bf897aee03dc8d982 Mon Sep 17 00:00:00 2001 From: Aigio Liu Date: Wed, 4 Aug 2021 19:25:54 +0800 Subject: [PATCH] fix DesktopBrider BootAutoStart --- .../DesktopBridgeHelper2.cs | 2 + src/ST.Client.Desktop.Avalonia.App/Program.cs | 19 ++++ .../WindowsDesktopPlatformServiceImpl.cs | 94 ++++++++++++------- .../Services/IDesktopPlatformService.cs | 2 + .../UI/Resx/AppResources.Designer.cs | 9 ++ .../UI/Resx/AppResources.resx | 5 +- 6 files changed, 98 insertions(+), 33 deletions(-) diff --git a/src/ST.Client.Desktop.Avalonia.App.Bridge/DesktopBridgeHelper2.cs b/src/ST.Client.Desktop.Avalonia.App.Bridge/DesktopBridgeHelper2.cs index fb16d1e87..91765e84e 100644 --- a/src/ST.Client.Desktop.Avalonia.App.Bridge/DesktopBridgeHelper2.cs +++ b/src/ST.Client.Desktop.Avalonia.App.Bridge/DesktopBridgeHelper2.cs @@ -1,3 +1,4 @@ +using System.Runtime.Versioning; using Windows.ApplicationModel; // ReSharper disable once CheckNamespace @@ -5,6 +6,7 @@ namespace System.Application { public static class DesktopBridgeHelper { + [SupportedOSPlatform("Windows10.0.10240.0")] public static bool Init(int min_os_build = 17763) { if (DI.Platform != Platform.Windows) return false; diff --git a/src/ST.Client.Desktop.Avalonia.App/Program.cs b/src/ST.Client.Desktop.Avalonia.App/Program.cs index e4f8b1d82..c82e92305 100644 --- a/src/ST.Client.Desktop.Avalonia.App/Program.cs +++ b/src/ST.Client.Desktop.Avalonia.App/Program.cs @@ -1,6 +1,8 @@ using NLog; +using System.Application.Services; using System.Collections.Generic; using System.Linq; +using System.Runtime.Versioning; namespace System.Application.UI { @@ -9,14 +11,31 @@ namespace System.Application.UI static readonly HashSet exceptions = new(); static readonly object lock_global_ex_log = new(); +#if WINDOWS_DESKTOP_BRIDGE + static string[] OnActivated(string[] main_args, global::Windows.ApplicationModel.Activation.IActivatedEventArgs args) + { + if (args.Kind == global::Windows.ApplicationModel.Activation.ActivationKind.StartupTask) + { + // 静默启动(不弹窗口) + return IDesktopPlatformService.SystemBootRunArguments.Split(' '); + } + return main_args; + } +#endif + // Initialization code. Don't use any Avalonia, third-party APIs or any // SynchronizationContext-reliant code before AppMain is called: things aren't initialized // yet and stuff might break. [STAThread] +#if WINDOWS_DESKTOP_BRIDGE + [SupportedOSPlatform("Windows10.0.17763.0")] +#endif static int Main(string[] args) { #if WINDOWS_DESKTOP_BRIDGE if (!DesktopBridgeHelper.Init()) return 0; + var activatedArgs = global::Windows.ApplicationModel.AppInstance.GetActivatedEventArgs(); + if (activatedArgs != null) args = OnActivated(args, activatedArgs); #elif !__MOBILE__ #if MAC AppDelegateHelper.Init(args); diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.cs index f349a3f66..237a08515 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.cs @@ -3,16 +3,15 @@ using Microsoft.Win32; using Microsoft.Win32.TaskScheduler; using System.Application.Models; using System.Application.UI; +using System.Application.UI.Resx; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Management; -using System.Reflection; using System.Runtime.Versioning; -using System.Security.Cryptography; using System.Security.Principal; -using System.Threading; +using Windows.ApplicationModel; namespace System.Application.Services.Implementation { @@ -122,44 +121,76 @@ namespace System.Application.Services.Implementation } } - public void SetBootAutoStart(bool isAutoStart, string name) + /// + /// UWP 的开机自启 TaskId,在 Package.appxmanifest 中设定 + /// + const string BootAutoStartTaskId = "BootAutoStartTask"; + + public async void SetBootAutoStart(bool isAutoStart, string name) { - global::Windows.ApplicationModel.AppInstance.GetActivatedEventArgs() - global::Windows.UI.ap - //global::Windows.ApplicationModel.app - // 开机启动使用 taskschd.msc 实现 - try + if (DI.IsDesktopBridge) { - var identity = WindowsIdentity.GetCurrent(); - var hasSid = identity.User?.IsAccountSid() ?? false; - var userId = hasSid ? identity.User!.ToString() : identity.Name; - var tdName = hasSid ? userId : userId.Replace(Path.DirectorySeparatorChar, '_'); - tdName = $"{name}_{{{tdName}}}"; + // https://blogs.windows.com/windowsdeveloper/2017/08/01/configure-app-start-log/ + // https://blog.csdn.net/lh275985651/article/details/109360162 + // https://www.cnblogs.com/wpinfo/p/uwp_auto_startup.html + // 还需要通过 global::Windows.ApplicationModel.AppInstance.GetActivatedEventArgs() 判断为自启时最小化,不能通过参数启动 + var startupTask = await StartupTask.GetAsync(BootAutoStartTaskId); if (isAutoStart) { - using var td = TaskService.Instance.NewTask(); - td.RegistrationInfo.Description = name + " System Boot Run"; - td.Settings.Priority = ProcessPriorityClass.Normal; - td.Settings.ExecutionTimeLimit = new TimeSpan(0); - td.Settings.AllowHardTerminate = false; - td.Settings.StopIfGoingOnBatteries = false; - td.Settings.DisallowStartIfOnBatteries = false; - td.Triggers.Add(new LogonTrigger { UserId = userId }); - td.Actions.Add(new ExecAction(AppHelper.ProgramName, "-clt c -silence", IOPath.BaseDirectory)); - if (IsAdministrator) - td.Principal.RunLevel = TaskRunLevel.Highest; - TaskService.Instance.RootFolder.RegisterTaskDefinition(tdName, td); + var startupTaskState = startupTask.State; + if (startupTask.State == StartupTaskState.Disabled) + { + startupTaskState = await startupTask.RequestEnableAsync(); + } + if (startupTaskState != StartupTaskState.Enabled && + startupTaskState != StartupTaskState.EnabledByPolicy) + { + Toast.Show(AppResources.SetBootAutoStartTrueFail_.Format(startupTaskState)); + } } else { - TaskService.Instance.RootFolder.DeleteTask(name, exceptionOnNotExists: false); - TaskService.Instance.RootFolder.DeleteTask(tdName, exceptionOnNotExists: false); + startupTask.Disable(); } } - catch (Exception e) + else { - Log.Error(TAG, e, - "SetBootAutoStart Fail, isAutoStart: {0}, name: {1}.", isAutoStart, name); + // 开机启动使用 taskschd.msc 实现 + try + { + var identity = WindowsIdentity.GetCurrent(); + var hasSid = identity.User?.IsAccountSid() ?? false; + var userId = hasSid ? identity.User!.ToString() : identity.Name; + var tdName = hasSid ? userId : userId.Replace(Path.DirectorySeparatorChar, '_'); + tdName = $"{name}_{{{tdName}}}"; + if (isAutoStart) + { + using var td = TaskService.Instance.NewTask(); + td.RegistrationInfo.Description = name + " System Boot Run"; + td.Settings.Priority = ProcessPriorityClass.Normal; + td.Settings.ExecutionTimeLimit = new TimeSpan(0); + td.Settings.AllowHardTerminate = false; + td.Settings.StopIfGoingOnBatteries = false; + td.Settings.DisallowStartIfOnBatteries = false; + td.Triggers.Add(new LogonTrigger { UserId = userId }); + td.Actions.Add(new ExecAction(AppHelper.ProgramName, + IDesktopPlatformService.SystemBootRunArguments, + IOPath.BaseDirectory)); + if (IsAdministrator) + td.Principal.RunLevel = TaskRunLevel.Highest; + TaskService.Instance.RootFolder.RegisterTaskDefinition(tdName, td); + } + else + { + TaskService.Instance.RootFolder.DeleteTask(name, exceptionOnNotExists: false); + TaskService.Instance.RootFolder.DeleteTask(tdName, exceptionOnNotExists: false); + } + } + catch (Exception e) + { + Log.Error(TAG, e, + "SetBootAutoStart Fail, isAutoStart: {0}, name: {1}.", isAutoStart, name); + } } } @@ -249,7 +280,6 @@ namespace System.Application.Services.Implementation } catch { - } return default; } diff --git a/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs b/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs index 1a4cd7fa2..e13868a6b 100644 --- a/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs +++ b/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs @@ -126,6 +126,8 @@ namespace System.Application.Services /// string? GetFileName(TextReaderProvider provider); + const string SystemBootRunArguments = "-clt c -silence"; + /// /// 设置开机自启动 /// diff --git a/src/ST.Client.Desktop/UI/Resx/AppResources.Designer.cs b/src/ST.Client.Desktop/UI/Resx/AppResources.Designer.cs index 3ea11a5d7..ff594a63d 100644 --- a/src/ST.Client.Desktop/UI/Resx/AppResources.Designer.cs +++ b/src/ST.Client.Desktop/UI/Resx/AppResources.Designer.cs @@ -3033,6 +3033,15 @@ namespace System.Application.UI.Resx { } } + /// + /// 查找类似 启用开机自启动失败,原因: {0} 的本地化字符串。 + /// + public static string SetBootAutoStartTrueFail_ { + get { + return ResourceManager.GetString("SetBootAutoStartTrueFail_", resourceCulture); + } + } + /// /// 查找类似 设置 的本地化字符串。 /// diff --git a/src/ST.Client.Desktop/UI/Resx/AppResources.resx b/src/ST.Client.Desktop/UI/Resx/AppResources.resx index 2e939c004..4d954454f 100644 --- a/src/ST.Client.Desktop/UI/Resx/AppResources.resx +++ b/src/ST.Client.Desktop/UI/Resx/AppResources.resx @@ -1516,4 +1516,7 @@ 计算中... - + + 启用开机自启动失败,原因: {0} + + \ No newline at end of file