当一项计划任务完成后,我希望另一项任务立即启动。任务 #1 已经有 32 个操作,因此我无法添加其他操作。所以我想“哦,我只需将单个任务拆分为多个任务并将它们链接在一起”但那么我如何触发任务 #2 仅在任务 #1 结束时启动(并且始终启动)?
我很惊讶这样的功能在任务计划程序中不可用并且/或者不直观。
答案1
我决定创建CMD
脚本并将所有顺序命令粘贴在那里。然后只需在任务计划程序中将该 CMD 文件作为单个操作运行即可。我只是echo
在每个命令后加上自己的自定义日志以及时间戳,以便我可以跟踪进度。我仍然不知道如何打印 ERRORLEVEL 代码。除了拥有无限的操作之外,我还可以为每个操作添加注释,而这是我无法通过任务计划程序操作做到的。
要静默运行(没有 CMD 控制台窗口),您可以使用nircmd或者静默命令脚本。
我仍然在下面保留了原始答案,因为它可能会帮助那些想要专门使用任务计划程序的人。或者需要弄清楚如何实现基于事件的触发。
经过彻底搜索后,我发现一篇博客文章很久以前就弄清楚了这一点。所以我会把它复制到这里,并附上更新的步骤,以便更容易遵循。基本上你有 3 个选择:
- 如果你的任务
X
有<=
32 个动作,那么只需向任务添加一个新动作即可X
。如果你的任务X
有>
32 个动作,那么你必须 - 将任务拆分
X
为多个任务,并将每个后续任务设置为在前一个任务完成后按顺序运行[如下所示] - 使用第三方软件,如z-cron
拆分任务并按顺序运行
无论您是达到了任务中 32 个操作的限制X
,还是只是想将一些操作组织到不同的任务中,让它们一个接一个运行的秘诀是使用X+1
自定义事件触发器设置任务,该触发器扫描特定事件日志并查找Task Completed
特定任务(序列中的前一个任务,或X
在本例中为任务)中的事件 102。
X
首先,如果您还没有 设置任务,我们需要设置该任务所需的所有操作。并成功运行任务X
至少1次。 我的任务在屏幕截图中X
被调用Ping
。然后查看历史记录日志,其中应该将事件 102 排在顶部。您可以event details
从右键单击上下文菜单中进行选择。- 点击DetailsTab 并选择XML View。您要提取 4 个标签/属性:
Provider-Name:
Microsoft-Windows-TaskScheduler
EventID:102
Channel:Microsoft-Windows-TaskScheduler/Operational
TaskName:\Ping
] TaskName:是最重要的
3. 设置任务X+1
(我会调用Pinging #2
)。重要的是触发器,它仅基于on an event
。
4. 事件必须自定义。您可以跳至下一步复制final code
/粘贴。
* 选择custom广播后,New Event Filter,选择广播by source并选择TaskScheduler
事件源。事件日志将预先填充一些事件日志类型。* 转到事件日志下拉菜单并取消选中除以下所有日志之外Microsoft-Windows-TaskScheduler/Operational。下面的截图希望能澄清一些事情 * 切换到XML tab你会看到类似这样的内容
<QueryList>
<Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
<Select Path="Microsoft-Windows-TaskScheduler/Operational">*[System[Provider[@Name='Microsoft-Windows-TaskScheduler']]]</Select>
</Query>
</QueryList>
5. 在 XML 选项卡上,您将检查Edit query manually并回答yes警告提示。因此 XML 可以为空白,此时这无关紧要,因为您将从此处手动编辑或复制完整代码。
*[System[Provider[@Name='Microsoft-Windows-TaskScheduler']]]
将被编辑成为*[EventData[@Name='TaskSuccessEvent'][Data[@Name='TaskName']='\Ping']]
最终的代码将如下所示
<QueryList>
<Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
<Select Path="Microsoft-Windows-TaskScheduler/Operational">*[EventData[@Name='TaskSuccessEvent'][Data[@Name='TaskName']='\Ping']]</Select>
</Query>
</QueryList>
- 测试一下是否可行。运行任务
X
,当任务完全完成后,任务X+1
应立即开始运行。
故障排除
我的程序在 Windows 10 和 Win 2012R2 上运行良好。我认为其他 Windows 版本也应该可以运行。如果运行不正常,则很可能是以下原因导致错误:
- 仔细检查手动查询 XML,以确保语法正确. 包括撇号的类型'或引号"用过的。
我会尝试一个简单的任务和简单的操作,比如ping
使用cmd
可以用 notepad++ 编辑的文件
- 确保任务计划程序History已启用。无论如何,您都需要它来捕获
TaskName:
上述过程中显示的内容。
- 确保任务计划程序Operational Logs已启用。
Event Viewer→ Applications and Services Log→ Microsoft→ Windows→ Task Scheduler→ Operational→ 右键单击它,(或转到右侧窗格)Properties
确保日志已启用!
最后 3 张图片归功于 @beatcracker 和他的相关计划任务在此发布。
- [不太可能] 您正在运行的程序应该先完成其任务,然后才向 [windows 操作系统事件日志] 指示任务已完成。这就是为什么仅使用批处理文件不足以处理可能出现异常的程序的原因。根据我的经验,我的所有程序实际上都在终止程序并向 windows 报告它已完成/退出之前完成了它们的任务。
但是当使用start
cmd 命令时,您可能需要添加/w
或/WAIT
参数,以确保start
启动的特定程序将等待该程序完成后再移动到下一个命令/退出。
例子start /B /w ping -n 1 -w 3000 -l 40 192.168.0.1
现在,为什么 Winblows 不让用户通过 GUI 轻松实现这种按顺序启动任务(而不仅仅是操作)的功能(和/或即使需要自定义 xml 也要有很好的文档记录)呢......嗯......典型的 Micros**t 思维。或者允许在单个任务中执行超过 32 个操作?这是 Windows 10,不是 Windows 95。无论如何,我希望这能对某些人有所帮助。
答案2
基于 Jon Grah 的解决方案,我有一个小插件。
如果你在任务计划程序中有一个目录,你可以像这样引用它。
'\Test\Test1' - 这意味着目录是 Test。任务名称是 Test1。
在自定义触发器中它看起来像这样:
<QueryList>
<Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
<Select Path="Microsoft-Windows-TaskScheduler/Operational">*[EventData[@Name='TaskSuccessEvent'][Data[@Name='TaskName']='\Test\Test1']]</Select>
</Query>
</QueryList>