use WScript.Shell to run scheduled tasks

This commit is contained in:
DismissedLight
2023-02-09 19:23:24 +08:00
parent 165c33ef2c
commit 98f18f91d8
7 changed files with 50 additions and 52 deletions

View File

@@ -10,9 +10,7 @@ using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Service.DailyNote;
using Snap.Hutao.Service.Metadata;
using Snap.Hutao.Service.Navigation;
#if RELEASE
using System.Security.Principal;
#endif
namespace Snap.Hutao.Core.LifeCycle;
@@ -39,15 +37,11 @@ internal static class Activation
/// <returns>是否提升了权限</returns>
public static bool GetElevated()
{
#if RELEASE
using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
{
WindowsPrincipal principal = new(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
#else
return true;
#endif
}
/// <summary>

View File

@@ -40,7 +40,7 @@ public static class AppActivationArgumentsExtensions
arguments = null;
if (activatedEventArgs.Data is ILaunchActivatedEventArgs launchArgs)
{
arguments = launchArgs.Arguments;
arguments = launchArgs.Arguments.Trim();
return true;
}

View File

@@ -2,7 +2,9 @@
// Licensed under the MIT license.
using Microsoft.Win32.TaskScheduler;
using System.IO;
using System.Runtime.InteropServices;
using Windows.Storage;
using SchedulerTask = Microsoft.Win32.TaskScheduler.Task;
namespace Snap.Hutao.Core;
@@ -23,23 +25,16 @@ internal static class ScheduleTaskHelper
{
try
{
// TODO: 似乎可以不删除任务,直接注册已经包含了更新功能
SchedulerTask? targetTask = TaskService.Instance.GetTask(DailyNoteRefreshTaskName);
if (targetTask != null)
{
TaskService.Instance.RootFolder.DeleteTask(DailyNoteRefreshTaskName);
}
TaskDefinition task = TaskService.Instance.NewTask();
task.RegistrationInfo.Description = SH.CoreScheduleTaskHelperDailyNoteRefreshTaskDescription;
task.Triggers.Add(new TimeTrigger() { Repetition = new(TimeSpan.FromSeconds(interval), TimeSpan.Zero), });
task.Actions.Add("explorer", "hutao://DailyNote/Refresh");
string scriptPath = EnsureWScriptCreated("DailyNoteRefresh", "hutao://DailyNote/Refresh");
task.Actions.Add("wscript", $@"/b ""{scriptPath}""");
TaskService.Instance.RootFolder.RegisterTaskDefinition(DailyNoteRefreshTaskName, task);
return true;
}
catch (Exception ex)
catch (Exception)
{
_ = ex;
return false;
}
}
@@ -69,4 +64,19 @@ internal static class ScheduleTaskHelper
return false;
}
}
private static string EnsureWScriptCreated(string name, string url, bool forceCreate = false)
{
string tempFolder = ApplicationData.Current.TemporaryFolder.Path;
string fullName = Path.Combine(tempFolder, "Script", $"{name}.vbs");
if (!File.Exists(fullName) || forceCreate)
{
Directory.CreateDirectory(Path.Combine(tempFolder, "Script"));
string script = $"""CreateObject("WScript.Shell").Run "cmd /c start {url}", 0, False""";
File.WriteAllText(fullName, script);
}
return fullName;
}
}

View File

@@ -34,16 +34,6 @@ public class UserAndUid
/// </summary>
public PlayerUid Uid { get; private set; }
/// <summary>
/// 从用户与选中的角色转换
/// </summary>
/// <param name="user">角色</param>
/// <returns>用户与角色</returns>
public static UserAndUid FromUser(User user)
{
return new UserAndUid(user.Entity, user.SelectedUserGameRole!);
}
/// <summary>
/// 尝试转换到用户与角色
/// </summary>
@@ -54,7 +44,7 @@ public class UserAndUid
{
if (user != null && user.SelectedUserGameRole != null)
{
userAndUid = FromUser(user);
userAndUid = new UserAndUid(user.Entity, user.SelectedUserGameRole!);
return true;
}

View File

@@ -77,7 +77,7 @@ internal partial class MetadataService : IMetadataService, IMetadataServiceIniti
logger.LogInformation(EventIds.MetadataInitialization, "Metadata initializaion begin");
isInitialized = await TryUpdateMetadataAsync(token).ConfigureAwait(false);
initializeCompletionSource.SetResult();
initializeCompletionSource.TrySetResult();
logger.LogInformation(EventIds.MetadataInitialization, "Metadata initializaion completed in {time}ms", stopwatch.GetElapsedTime().TotalMilliseconds);
}

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Model.Binding.Cultivation;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Service.Abstraction;
@@ -19,8 +20,8 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Scoped)]
internal class CultivationViewModel : Abstraction.ViewModel
{
private readonly IServiceProvider serviceProvider;
private readonly ICultivationService cultivationService;
private readonly IInfoBarService infoBarService;
private readonly IMetadataService metadataService;
private readonly ILogger<CultivationViewModel> logger;
@@ -35,20 +36,15 @@ internal class CultivationViewModel : Abstraction.ViewModel
/// <summary>
/// 构造一个新的养成视图模型
/// </summary>
/// <param name="cultivationService">养成服务</param>
/// <param name="infoBarService">信息服务</param>
/// <param name="serviceProvider">服务提供器</param>
/// <param name="metadataService">元数据服务</param>
/// <param name="logger">日志器</param>
public CultivationViewModel(
ICultivationService cultivationService,
IInfoBarService infoBarService,
IMetadataService metadataService,
ILogger<CultivationViewModel> logger)
public CultivationViewModel(IServiceProvider serviceProvider)
{
this.cultivationService = cultivationService;
this.infoBarService = infoBarService;
this.metadataService = metadataService;
this.logger = logger;
cultivationService = serviceProvider.GetRequiredService<ICultivationService>();
metadataService = serviceProvider.GetRequiredService<IMetadataService>();
logger = serviceProvider.GetRequiredService<ILogger<CultivationViewModel>>();
this.serviceProvider = serviceProvider;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
AddProjectCommand = new AsyncRelayCommand(AddProjectAsync);
@@ -56,7 +52,7 @@ internal class CultivationViewModel : Abstraction.ViewModel
RemoveEntryCommand = new AsyncRelayCommand<Model.Binding.Cultivation.CultivateEntry>(RemoveEntryAsync);
SaveInventoryItemCommand = new RelayCommand<Model.Binding.Inventory.InventoryItem>(SaveInventoryItem);
NavigateToPageCommand = new RelayCommand<string>(NavigateToPage);
FinishStateCommand = new RelayCommand<Model.Binding.Cultivation.CultivateItem>(FlipFinishedState);
FinishStateCommand = new RelayCommand<Model.Binding.Cultivation.CultivateItem>(UpdateFinishedState);
}
/// <summary>
@@ -153,6 +149,7 @@ internal class CultivationViewModel : Abstraction.ViewModel
if (isOk)
{
ProjectAddResult result = await cultivationService.TryAddProjectAsync(project).ConfigureAwait(false);
IInfoBarService infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
switch (result)
{
@@ -223,7 +220,7 @@ internal class CultivationViewModel : Abstraction.ViewModel
}
}
private void FlipFinishedState(Model.Binding.Cultivation.CultivateItem? item)
private void UpdateFinishedState(Model.Binding.Cultivation.CultivateItem? item)
{
if (item != null)
{
@@ -258,8 +255,9 @@ internal class CultivationViewModel : Abstraction.ViewModel
{
if (typeString != null)
{
Type? pageType = Type.GetType(typeString);
Ioc.Default.GetRequiredService<INavigationService>().Navigate(pageType!, INavigationAwaiter.Default, true);
serviceProvider
.GetRequiredService<INavigationService>()
.Navigate(Type.GetType(typeString)!, INavigationAwaiter.Default, true);
}
}
}

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Core;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Model;
@@ -22,6 +23,7 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Scoped)]
internal class DailyNoteViewModel : Abstraction.ViewModel
{
private readonly IServiceProvider serviceProvider;
private readonly IUserService userService;
private readonly IDailyNoteService dailyNoteService;
private readonly AppDbContext appDbContext;
@@ -48,10 +50,12 @@ internal class DailyNoteViewModel : Abstraction.ViewModel
/// <summary>
/// 构造一个新的实时便笺视图模型
/// </summary>
/// <param name="serviceProvider">服务提供器</param>
/// <param name="userService">用户服务</param>
/// <param name="dailyNoteService">实时便笺服务</param>
/// <param name="appDbContext">数据库上下文</param>
public DailyNoteViewModel(
IServiceProvider serviceProvider,
IUserService userService,
IDailyNoteService dailyNoteService,
AppDbContext appDbContext)
@@ -59,6 +63,7 @@ internal class DailyNoteViewModel : Abstraction.ViewModel
this.userService = userService;
this.dailyNoteService = dailyNoteService;
this.appDbContext = appDbContext;
this.serviceProvider = serviceProvider;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
TrackRoleCommand = new AsyncRelayCommand<UserAndUid>(TrackRoleAsync);
@@ -179,7 +184,7 @@ internal class DailyNoteViewModel : Abstraction.ViewModel
}
catch (Core.ExceptionService.UserdataCorruptedException ex)
{
Ioc.Default.GetRequiredService<IInfoBarService>().Error(ex);
serviceProvider.GetRequiredService<IInfoBarService>().Error(ex);
return;
}
@@ -190,9 +195,10 @@ internal class DailyNoteViewModel : Abstraction.ViewModel
await ThreadHelper.SwitchToMainThreadAsync();
refreshSecondsEntry = appDbContext.Settings.SingleOrAdd(SettingEntry.DailyNoteRefreshSeconds, "480");
selectedRefreshTime = refreshTimes.Single(t => t.Value == refreshSecondsEntry.GetInt32());
int refreshSeconds = refreshSecondsEntry.GetInt32();
selectedRefreshTime = refreshTimes.Single(t => t.Value == refreshSeconds);
OnPropertyChanged(nameof(SelectedRefreshTime));
ScheduleTaskHelper.RegisterForDailyNoteRefresh(480);
ScheduleTaskHelper.RegisterForDailyNoteRefresh(refreshSeconds);
reminderNotifyEntry = appDbContext.Settings.SingleOrAdd(SettingEntry.DailyNoteReminderNotify, SettingEntryHelper.FalseString);
isReminderNotification = reminderNotifyEntry.GetBoolean();
@@ -204,9 +210,9 @@ internal class DailyNoteViewModel : Abstraction.ViewModel
}
await ThreadHelper.SwitchToBackgroundAsync();
ObservableCollection<DailyNoteEntry> temp = await dailyNoteService.GetDailyNoteEntriesAsync().ConfigureAwait(false);
ObservableCollection<DailyNoteEntry> entries = await dailyNoteService.GetDailyNoteEntriesAsync().ConfigureAwait(false);
await ThreadHelper.SwitchToMainThreadAsync();
DailyNoteEntries = temp;
DailyNoteEntries = entries;
}
catch (OperationCanceledException)
{
@@ -255,7 +261,7 @@ internal class DailyNoteViewModel : Abstraction.ViewModel
}
else
{
Ioc.Default.GetRequiredService<IInfoBarService>().Warning(SH.MustSelectUserAndUid);
serviceProvider.GetRequiredService<IInfoBarService>().Warning(SH.MustSelectUserAndUid);
}
}
}
}