From 59af1e468d9f7b725b5397627ccca496c4c3581f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AD=B1=E5=82=91?= Date: Sat, 10 Dec 2022 17:50:35 +0800 Subject: [PATCH] Add Task Page (#166) --- .../Forms/FormMain.Designer.cs | 9 + Source/GrasscutterTools/Forms/FormMain.cs | 1 + Source/GrasscutterTools/Forms/FormMain.resx | 33 ++- .../GrasscutterTools/GrasscutterTools.csproj | 9 + Source/GrasscutterTools/Pages/BasePage.cs | 27 +- .../Pages/PageTasks.Designer.cs | 250 +++++++++++++++++ Source/GrasscutterTools/Pages/PageTasks.cs | 265 ++++++++++++++++++ Source/GrasscutterTools/Pages/PageTasks.resx | 120 ++++++++ .../Properties/Resources.Designer.cs | 9 + .../Properties/Resources.en-us.resx | 3 + .../Properties/Resources.resx | 3 + .../Properties/Resources.ru-ru.resx | 3 + .../Properties/Resources.zh-TW.resx | 3 + 13 files changed, 731 insertions(+), 4 deletions(-) create mode 100644 Source/GrasscutterTools/Pages/PageTasks.Designer.cs create mode 100644 Source/GrasscutterTools/Pages/PageTasks.cs create mode 100644 Source/GrasscutterTools/Pages/PageTasks.resx diff --git a/Source/GrasscutterTools/Forms/FormMain.Designer.cs b/Source/GrasscutterTools/Forms/FormMain.Designer.cs index 63cc11b..b6fd514 100644 --- a/Source/GrasscutterTools/Forms/FormMain.Designer.cs +++ b/Source/GrasscutterTools/Forms/FormMain.Designer.cs @@ -50,6 +50,7 @@ namespace GrasscutterTools.Forms this.TCMain = new System.Windows.Forms.TabControl(); this.TPMail = new System.Windows.Forms.TabPage(); this.MenuSpawnEntityFilter = new System.Windows.Forms.ContextMenuStrip(this.components); + this.TPLoopTasks = new System.Windows.Forms.TabPage(); this.GrpCommand.SuspendLayout(); this.TCMain.SuspendLayout(); this.SuspendLayout(); @@ -177,6 +178,7 @@ namespace GrasscutterTools.Forms this.TCMain.Controls.Add(this.TPWeapon); this.TCMain.Controls.Add(this.TPManage); this.TCMain.Controls.Add(this.TPMail); + this.TCMain.Controls.Add(this.TPLoopTasks); this.TCMain.Controls.Add(this.TPQuest); this.TCMain.Controls.Add(this.TPScene); this.TCMain.Controls.Add(this.TPAbout); @@ -194,6 +196,12 @@ namespace GrasscutterTools.Forms this.MenuSpawnEntityFilter.Name = "MenuSpawnEntityFilter"; resources.ApplyResources(this.MenuSpawnEntityFilter, "MenuSpawnEntityFilter"); // + // TPLoopTasks + // + resources.ApplyResources(this.TPLoopTasks, "TPLoopTasks"); + this.TPLoopTasks.Name = "TPLoopTasks"; + this.TPLoopTasks.UseVisualStyleBackColor = true; + // // FormMain // resources.ApplyResources(this, "$this"); @@ -234,5 +242,6 @@ namespace GrasscutterTools.Forms private System.Windows.Forms.TabControl TCMain; private System.Windows.Forms.TabPage TPMail; private System.Windows.Forms.ContextMenuStrip MenuSpawnEntityFilter; + private System.Windows.Forms.TabPage TPLoopTasks; } } diff --git a/Source/GrasscutterTools/Forms/FormMain.cs b/Source/GrasscutterTools/Forms/FormMain.cs index af18f9c..c1d171d 100644 --- a/Source/GrasscutterTools/Forms/FormMain.cs +++ b/Source/GrasscutterTools/Forms/FormMain.cs @@ -97,6 +97,7 @@ namespace GrasscutterTools.Forms TPWeapon.Controls.Add(CreatePage()); TPManage.Controls.Add(CreatePage()); TPMail.Controls.Add(CreatePage()); + TPLoopTasks.Controls.Add(CreatePage()); TPQuest.Controls.Add(CreatePage()); TPScene.Controls.Add(CreatePage()); TPAbout.Controls.Add(CreatePage()); diff --git a/Source/GrasscutterTools/Forms/FormMain.resx b/Source/GrasscutterTools/Forms/FormMain.resx index 5ea4e53..a4fcfee 100644 --- a/Source/GrasscutterTools/Forms/FormMain.resx +++ b/Source/GrasscutterTools/Forms/FormMain.resx @@ -316,7 +316,7 @@ TCMain - 12 + 13 4, 26 @@ -370,7 +370,7 @@ TCMain - 11 + 12 4, 26 @@ -508,7 +508,7 @@ TCMain - 10 + 11 4, 26 @@ -621,6 +621,33 @@ 9 + + 4, 26 + + + 3, 3, 3, 3 + + + 652, 245 + + + 17 + + + 循环 + + + TPLoopTasks + + + System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TCMain + + + 10 + 12, 12 diff --git a/Source/GrasscutterTools/GrasscutterTools.csproj b/Source/GrasscutterTools/GrasscutterTools.csproj index 948d09a..4026b2e 100644 --- a/Source/GrasscutterTools/GrasscutterTools.csproj +++ b/Source/GrasscutterTools/GrasscutterTools.csproj @@ -238,6 +238,12 @@ PageSpawn.cs + + UserControl + + + PageTasks.cs + @@ -496,6 +502,9 @@ PageSpawn.cs + + PageTasks.cs + ResXFileCodeGenerator Resources.zh-TW.Designer.cs diff --git a/Source/GrasscutterTools/Pages/BasePage.cs b/Source/GrasscutterTools/Pages/BasePage.cs index bac567e..da6108c 100644 --- a/Source/GrasscutterTools/Pages/BasePage.cs +++ b/Source/GrasscutterTools/Pages/BasePage.cs @@ -19,6 +19,7 @@ using System; using System.Drawing; +using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; @@ -51,7 +52,7 @@ namespace GrasscutterTools.Pages /// 参数 public SetCommandHandler SetCommand { get; set; } - public delegate Task RunCommandsHandler(string[] commands); + public delegate Task RunCommandsHandler(params string[] commands); /// /// 运行命令 @@ -63,6 +64,30 @@ namespace GrasscutterTools.Pages /// public Func GetCommand { get; set; } + /// + /// 运行原始命令(未处理的竖线分割命令文本) + /// + /// 未处理的竖线分割命令文本 + /// 是否运行成功 + protected async Task RunRawCommands(string commands) + { + if (commands.IndexOf('|') == -1) + return await RunCommands(FormatCommand(commands)); + else + return await RunCommands(commands.Split('|').Select(it => FormatCommand(it)).ToArray()); + } + + /// + /// 格式化命令 + /// (去除收尾空白,替换换行) + /// + /// 原始输入 + /// 格式化后可执行命令 + private string FormatCommand(string raw) + { + return raw.Trim().Replace("\\r", "\r").Replace("\\n", "\n"); + } + #endregion - 命令相关 - #region - 生命周期事件 - diff --git a/Source/GrasscutterTools/Pages/PageTasks.Designer.cs b/Source/GrasscutterTools/Pages/PageTasks.Designer.cs new file mode 100644 index 0000000..36908b5 --- /dev/null +++ b/Source/GrasscutterTools/Pages/PageTasks.Designer.cs @@ -0,0 +1,250 @@ +namespace GrasscutterTools.Pages +{ + partial class PageTasks + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.GrpTasks = new System.Windows.Forms.GroupBox(); + this.ListTasks = new System.Windows.Forms.ListView(); + this.ColTag = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.ColContent = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.ColDelay = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.ColCount = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.GrpTask = new System.Windows.Forms.GroupBox(); + this.BtnRemove = new System.Windows.Forms.Button(); + this.BtnAccept = new System.Windows.Forms.Button(); + this.NUDTriggerCount = new System.Windows.Forms.NumericUpDown(); + this.LblTriggerCount = new System.Windows.Forms.Label(); + this.DTPDelay = new System.Windows.Forms.DateTimePicker(); + this.LblDelay = new System.Windows.Forms.Label(); + this.TxtTag = new System.Windows.Forms.TextBox(); + this.LblTag = new System.Windows.Forms.Label(); + this.GrpTasks.SuspendLayout(); + this.GrpTask.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.NUDTriggerCount)).BeginInit(); + this.SuspendLayout(); + // + // GrpTasks + // + this.GrpTasks.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.GrpTasks.Controls.Add(this.ListTasks); + this.GrpTasks.Location = new System.Drawing.Point(3, 3); + this.GrpTasks.Name = "GrpTasks"; + this.GrpTasks.Size = new System.Drawing.Size(640, 183); + this.GrpTasks.TabIndex = 0; + this.GrpTasks.TabStop = false; + this.GrpTasks.Text = "任务列表"; + // + // ListTasks + // + this.ListTasks.AllowColumnReorder = true; + this.ListTasks.CheckBoxes = true; + this.ListTasks.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.ColTag, + this.ColContent, + this.ColDelay, + this.ColCount}); + this.ListTasks.Dock = System.Windows.Forms.DockStyle.Fill; + this.ListTasks.HideSelection = false; + this.ListTasks.Location = new System.Drawing.Point(3, 19); + this.ListTasks.MultiSelect = false; + this.ListTasks.Name = "ListTasks"; + this.ListTasks.Size = new System.Drawing.Size(634, 161); + this.ListTasks.TabIndex = 0; + this.ListTasks.UseCompatibleStateImageBehavior = false; + this.ListTasks.View = System.Windows.Forms.View.Details; + this.ListTasks.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.ListTasks_ItemChecked); + this.ListTasks.SelectedIndexChanged += new System.EventHandler(this.ListTasks_SelectedIndexChanged); + // + // ColTag + // + this.ColTag.Text = "标签"; + this.ColTag.Width = 150; + // + // ColContent + // + this.ColContent.Text = "内容"; + this.ColContent.Width = 330; + // + // ColDelay + // + this.ColDelay.Text = "延迟"; + // + // ColCount + // + this.ColCount.Text = "次数"; + // + // GrpTask + // + this.GrpTask.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.GrpTask.Controls.Add(this.BtnRemove); + this.GrpTask.Controls.Add(this.BtnAccept); + this.GrpTask.Controls.Add(this.NUDTriggerCount); + this.GrpTask.Controls.Add(this.LblTriggerCount); + this.GrpTask.Controls.Add(this.DTPDelay); + this.GrpTask.Controls.Add(this.LblDelay); + this.GrpTask.Controls.Add(this.TxtTag); + this.GrpTask.Controls.Add(this.LblTag); + this.GrpTask.Location = new System.Drawing.Point(3, 186); + this.GrpTask.Name = "GrpTask"; + this.GrpTask.Size = new System.Drawing.Size(640, 50); + this.GrpTask.TabIndex = 1; + this.GrpTask.TabStop = false; + this.GrpTask.Text = "任务"; + // + // BtnRemove + // + this.BtnRemove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.BtnRemove.Location = new System.Drawing.Point(534, 18); + this.BtnRemove.Name = "BtnRemove"; + this.BtnRemove.Size = new System.Drawing.Size(100, 23); + this.BtnRemove.TabIndex = 7; + this.BtnRemove.Text = "× 删除"; + this.BtnRemove.UseVisualStyleBackColor = true; + this.BtnRemove.Click += new System.EventHandler(this.BtnRemove_Click); + // + // BtnAccept + // + this.BtnAccept.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.BtnAccept.Location = new System.Drawing.Point(428, 18); + this.BtnAccept.Name = "BtnAccept"; + this.BtnAccept.Size = new System.Drawing.Size(100, 23); + this.BtnAccept.TabIndex = 6; + this.BtnAccept.Text = "√ 确定"; + this.BtnAccept.UseVisualStyleBackColor = true; + this.BtnAccept.Click += new System.EventHandler(this.BtnAccept_Click); + // + // NUDTriggerCount + // + this.NUDTriggerCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.NUDTriggerCount.Location = new System.Drawing.Point(372, 19); + this.NUDTriggerCount.Maximum = new decimal(new int[] { + 1000, + 0, + 0, + 0}); + this.NUDTriggerCount.Minimum = new decimal(new int[] { + 1, + 0, + 0, + -2147483648}); + this.NUDTriggerCount.Name = "NUDTriggerCount"; + this.NUDTriggerCount.Size = new System.Drawing.Size(50, 23); + this.NUDTriggerCount.TabIndex = 5; + this.NUDTriggerCount.Value = new decimal(new int[] { + 1, + 0, + 0, + -2147483648}); + // + // LblTriggerCount + // + this.LblTriggerCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.LblTriggerCount.AutoSize = true; + this.LblTriggerCount.Location = new System.Drawing.Point(334, 22); + this.LblTriggerCount.Name = "LblTriggerCount"; + this.LblTriggerCount.Size = new System.Drawing.Size(32, 17); + this.LblTriggerCount.TabIndex = 4; + this.LblTriggerCount.Text = "次数"; + // + // DTPDelay + // + this.DTPDelay.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.DTPDelay.CustomFormat = ""; + this.DTPDelay.Format = System.Windows.Forms.DateTimePickerFormat.Time; + this.DTPDelay.Location = new System.Drawing.Point(258, 19); + this.DTPDelay.Name = "DTPDelay"; + this.DTPDelay.ShowUpDown = true; + this.DTPDelay.Size = new System.Drawing.Size(70, 23); + this.DTPDelay.TabIndex = 3; + this.DTPDelay.Value = new System.DateTime(2022, 12, 10, 0, 1, 0, 0); + // + // LblDelay + // + this.LblDelay.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.LblDelay.AutoSize = true; + this.LblDelay.Location = new System.Drawing.Point(220, 22); + this.LblDelay.Name = "LblDelay"; + this.LblDelay.Size = new System.Drawing.Size(32, 17); + this.LblDelay.TabIndex = 2; + this.LblDelay.Text = "延迟"; + // + // TxtTag + // + this.TxtTag.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TxtTag.Location = new System.Drawing.Point(49, 18); + this.TxtTag.Name = "TxtTag"; + this.TxtTag.Size = new System.Drawing.Size(165, 23); + this.TxtTag.TabIndex = 1; + // + // LblTag + // + this.LblTag.AutoSize = true; + this.LblTag.Location = new System.Drawing.Point(11, 21); + this.LblTag.Name = "LblTag"; + this.LblTag.Size = new System.Drawing.Size(32, 17); + this.LblTag.TabIndex = 0; + this.LblTag.Text = "标签"; + // + // PageTasks + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.GrpTask); + this.Controls.Add(this.GrpTasks); + this.Name = "PageTasks"; + this.GrpTasks.ResumeLayout(false); + this.GrpTask.ResumeLayout(false); + this.GrpTask.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.NUDTriggerCount)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox GrpTasks; + private System.Windows.Forms.GroupBox GrpTask; + private System.Windows.Forms.DateTimePicker DTPDelay; + private System.Windows.Forms.Label LblDelay; + private System.Windows.Forms.TextBox TxtTag; + private System.Windows.Forms.Label LblTag; + private System.Windows.Forms.NumericUpDown NUDTriggerCount; + private System.Windows.Forms.Label LblTriggerCount; + private System.Windows.Forms.Button BtnRemove; + private System.Windows.Forms.Button BtnAccept; + private System.Windows.Forms.ListView ListTasks; + private System.Windows.Forms.ColumnHeader ColTag; + private System.Windows.Forms.ColumnHeader ColContent; + private System.Windows.Forms.ColumnHeader ColDelay; + private System.Windows.Forms.ColumnHeader ColCount; + } +} diff --git a/Source/GrasscutterTools/Pages/PageTasks.cs b/Source/GrasscutterTools/Pages/PageTasks.cs new file mode 100644 index 0000000..141015d --- /dev/null +++ b/Source/GrasscutterTools/Pages/PageTasks.cs @@ -0,0 +1,265 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +using GrasscutterTools.Properties; +using GrasscutterTools.Utils; + +using Newtonsoft.Json; + +namespace GrasscutterTools.Pages +{ + internal partial class PageTasks : BasePage + { + private const string TAG = nameof(PageTasks); + + public PageTasks() + { + InitializeComponent(); + ListTasks.FullRowSelect = true; + if (DesignMode) return; + + InitTasks(); + } + + /// + /// 循环任务 + /// + private class LoopTask + { + /// + /// 任务标签 + /// + public string Tag { get; set; } + + /// + /// 任务内容 + /// + public string Content { get; set; } + + /// + /// 延迟时间(秒) + /// + public int DelayS { get; set; } + + /// + /// 触发次数 -1为无限循环 + /// + public int TriggerCount { get; set; } + } + + /// + /// 任务列表路径 + /// + private readonly string TasksJsonPath = Common.GetAppDataFile("Tasks.json"); + + /// + /// 任务集合 + /// + private List Tasks; + + /// + /// 运行中的任务集合 + /// + private readonly ConcurrentDictionary RunningTasks = new ConcurrentDictionary(); + + /// + /// 初始化任务集合 + /// + private void InitTasks() + { + if (File.Exists(TasksJsonPath)) + { + try + { + Tasks = JsonConvert.DeserializeObject>(File.ReadAllText(TasksJsonPath)); + ListTasks.Items.AddRange(Tasks.Select(t => TaskToViewItem(t)).ToArray()); + } + catch (Exception ex) + { + Tasks = new List(); + Logger.W(TAG, "Parsing Tasks json failed", ex); + } + } + else + { + Tasks = new List(); + } + } + + /// + /// 关闭时触发 + /// + public override void OnClosed() + { + // 取消所有正在运行的任务 + foreach (var cs in RunningTasks.Values) + cs.Cancel(); + // 清空列表 + RunningTasks.Clear(); + + // 保存任务列表 + File.WriteAllText(TasksJsonPath, JsonConvert.SerializeObject(Tasks)); + } + + /// + /// 任务转为列表项 + /// + /// 任务 + /// 列表项 + private static ListViewItem TaskToViewItem(LoopTask task) => new ListViewItem(new string[] + { + task.Tag, + task.Content, + TimeSpan.FromSeconds(task.DelayS).ToString(), + task.TriggerCount.ToString(), + }); + + /// + /// 列表选中项改变时触发 + /// + private void ListTasks_SelectedIndexChanged(object sender, EventArgs e) + { + if (ListTasks.SelectedIndices.Count == 0) return; + int i = ListTasks.SelectedIndices[0]; + var task = Tasks[i]; + TxtTag.Text = task.Tag; + DTPDelay.Value = DateTime.Today.Add(TimeSpan.FromSeconds(task.DelayS)); + NUDTriggerCount.Value = task.TriggerCount; + // 设置命令 + SetCommand(task.Content); + } + + /// + /// 点击确定按钮时触发 + /// + private void BtnAccept_Click(object sender, EventArgs e) + { + var tag = TxtTag.Text.Trim(); + var commands = GetCommand(); + var delay = DTPDelay.Value.TimeOfDay; + var count = (int)NUDTriggerCount.Value; + if (string.IsNullOrEmpty(tag) || string.IsNullOrEmpty(commands) || delay.Ticks == 0) + { + MessageBox.Show(Resources.EmptyInputTip, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + // 查找是否已经存在 + var i = Tasks.FindIndex(t => t.Tag == tag); + if (i == -1) + { + // 新建任务 + var t = new LoopTask + { + Tag = tag, + Content = commands, + DelayS = (int)delay.TotalSeconds, + TriggerCount = count, + }; + ListTasks.Items.Add(TaskToViewItem(t)); + Tasks.Add(t); + } + else + { + // 已存在的任务,确认是否正在运行中 + if (ListTasks.Items[i].Checked || RunningTasks.ContainsKey(tag)) + { + MessageBox.Show(Resources.TaskRunningCannotOperated, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + // 否则修改任务内容 + var task = Tasks[i]; + task.Content = commands; + task.DelayS = (int)delay.TotalSeconds; + task.TriggerCount = count; + ListTasks.Items[i] = TaskToViewItem(task); + } + } + + /// + /// 点击删除按钮时触发 + /// + private void BtnRemove_Click(object sender, EventArgs e) + { + var tag = TxtTag.Text.Trim(); + // 查找是否已经存在 + var i = Tasks.FindIndex(t => t.Tag == tag); + if (i == -1) return; + + if (ListTasks.Items[i].Checked || RunningTasks.ContainsKey(tag)) + { + MessageBox.Show(Resources.TaskRunningCannotOperated, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + // 删除实例 + ListTasks.Items.RemoveAt(i); + Tasks.RemoveAt(i); + } + + /// + /// 任务前复选框改变时触发 + /// + private void ListTasks_ItemChecked(object sender, ItemCheckedEventArgs e) + { + try + { + var item = e.Item; + if (item.Index < 0 || item.Index >= Tasks.Count) + return; + var task = Tasks[item.Index]; + // 先将旧的任务取消 + if (RunningTasks.TryRemove(task.Tag, out var source)) + source.Cancel(); + + if (item.Checked) + { + var cancelSource = new CancellationTokenSource(); + RunningTasks.TryAdd(task.Tag, cancelSource); + var token = cancelSource.Token; + Task.Run(async () => + { + try + { + Logger.I(TAG, $"Task \"{task.Tag}\" started"); + // 循环执行命令 + for (int c = 0; + !token.IsCancellationRequested + && (c < task.TriggerCount || task.TriggerCount <= 0); + c++) + { + // 延迟 + await Task.Delay(task.DelayS * 1000, token); + // 使用UI线程执行 + var ret = Invoke(new Func>(RunRawCommands), task.Content); + if (ret is Task b && b.Result == false) + break; + // 执行 + //if (!await RunRawCommands(task.Content)) + // break; + } + } + finally + { + // 任务结束后取消勾选状态 + BeginInvoke(new Action(() => item.Checked = false)); + Logger.I(TAG, $"Task \"{task.Tag}\" stoped"); + } + }, token); + } + } + catch (Exception ex) + { + Logger.E(TAG, "Start or Stop Task failed.", ex); + MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } +} \ No newline at end of file diff --git a/Source/GrasscutterTools/Pages/PageTasks.resx b/Source/GrasscutterTools/Pages/PageTasks.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Source/GrasscutterTools/Pages/PageTasks.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Source/GrasscutterTools/Properties/Resources.Designer.cs b/Source/GrasscutterTools/Properties/Resources.Designer.cs index 7566e81..422b46c 100644 --- a/Source/GrasscutterTools/Properties/Resources.Designer.cs +++ b/Source/GrasscutterTools/Properties/Resources.Designer.cs @@ -1185,6 +1185,15 @@ namespace GrasscutterTools.Properties { } } + /// + /// 查找类似 任务已经启动,无法操作 的本地化字符串。 + /// + internal static string TaskRunningCannotOperated { + get { + return ResourceManager.GetString("TaskRunningCannotOperated", resourceCulture); + } + } + /// /// 查找类似 提示 的本地化字符串。 /// diff --git a/Source/GrasscutterTools/Properties/Resources.en-us.resx b/Source/GrasscutterTools/Properties/Resources.en-us.resx index 87c8189..104159a 100644 --- a/Source/GrasscutterTools/Properties/Resources.en-us.resx +++ b/Source/GrasscutterTools/Properties/Resources.en-us.resx @@ -294,4 +294,7 @@ Improvement suggestions have been submitted, please use caution to send emails t All + + The task has already started and cannot be operated + \ No newline at end of file diff --git a/Source/GrasscutterTools/Properties/Resources.resx b/Source/GrasscutterTools/Properties/Resources.resx index 456bd3d..3e67354 100644 --- a/Source/GrasscutterTools/Properties/Resources.resx +++ b/Source/GrasscutterTools/Properties/Resources.resx @@ -306,4 +306,7 @@ 全部 + + 任务已经启动,无法操作 + \ No newline at end of file diff --git a/Source/GrasscutterTools/Properties/Resources.ru-ru.resx b/Source/GrasscutterTools/Properties/Resources.ru-ru.resx index 498c8ef..01eb659 100644 --- a/Source/GrasscutterTools/Properties/Resources.ru-ru.resx +++ b/Source/GrasscutterTools/Properties/Resources.ru-ru.resx @@ -282,4 +282,7 @@ Все + + Задача уже запущена и не может быть выполнена + \ No newline at end of file diff --git a/Source/GrasscutterTools/Properties/Resources.zh-TW.resx b/Source/GrasscutterTools/Properties/Resources.zh-TW.resx index 38507c4..896c1f3 100644 --- a/Source/GrasscutterTools/Properties/Resources.zh-TW.resx +++ b/Source/GrasscutterTools/Properties/Resources.zh-TW.resx @@ -288,4 +288,7 @@ 全部 + + 任務已經啟動,無法操作 + \ No newline at end of file