我在 Windows 2012 文件服务器上的任务计划程序中有一个任务。该任务必须在每周日晚上删除临时通用访问目录的内容。它在预定的时间运行并每次都报告成功,但目录内容不会被删除。
该任务包括以下批处理文件:
D:
cd D:\Shared\Temp\
del /Q /F /S "D:\Shared\Temp\*.*"
这是任务的 xml:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2014-06-16T12:13:45.8524361</Date>
<Author>OFFICE\Administrator</Author>
<Description>Weekly deletes the contents of the Temp directory</Description>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2014-06-22T20:00:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByWeek>
<DaysOfWeek>
<Sunday />
</DaysOfWeek>
<WeeksInterval>1</WeeksInterval>
</ScheduleByWeek>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>OFFICE\Administrator</UserId>
<LogonType>Password</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>false</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>true</WakeToRun>
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>"D:\IT\tempdelete.bat"</Command>
</Exec>
</Actions>
</Task>
我不明白为什么这个任务没有按预期完成。有经验的人能解释一下吗?
2014 年 8 月 11 日更新
这里还有另一个答案建议在我的批处理命令中进行以下编辑(我不知道为什么它被删除了):
D:
cd D:\Shared\Temp\
del /F /S "D:\Shared\Temp\*.*" 1> D:\my.log 2>&1
这个周末我运行了这个脚本。任务计划程序仍然声称该作业已成功完成,但这次我有一个矛盾的 my.log 文件:
The system cannot find the path specified.
我在脚本中看不到路径定义错误。指定的路径是正确的。
我是不是该不是按照 joeqwerty 所述更改目录?
或者
我也应该在括号中定义目录更改吗?
或者什么???
答案1
我能想到两种可能性。
1) 文件是在计划任务完成后添加的。但我怀疑您正在检查时间戳,并看到早于任务的日期。所以这可能不是问题所在。
2)一个或多个文件可能被另一个进程锁定,从而阻止删除。
不幸的是,如果失败,DEL 命令不会返回错误代码。它会将错误消息打印到 stderr,但返回的 ERRORLEVEL 始终为 0。
您可以使用 将 DEL 命令的 stderr 重定向到文件来确认锁定文件是否导致了问题2>somePath\someFile.log
。发生故障时,您应该会看到类似The process cannot access the file because it is being used by another process.
日志文件中的错误消息。
如果您想要检测一个或多个文件被锁定并采取行动,那么您可以使用以下变体如何在删除失败时停止批处理脚本。
set "locked="
for /r "D:\Shared\Temp" %%F in (.) do dir /a-d "%F" >nul 2>nul && (ren "%F\*" * || set locked=1)
if defined locked echo Take some action because files are locked.
如果一个或多个文件被锁定,则将文件重命名为原始名称将失败。但如果给定文件夹中没有文件,则不应进行测试。DIR /AD 命令检测给定文件夹是否包含文件。FOR /R 命令迭代所有文件夹,包括指定的根目录。
编辑
我应该进一步阅读我引用的链接。底部的答案提供了一种更直接的方法来检测删除失败,而无需使用额外的命令来检测打开的文件。只需检查 DEL 命令的 stderr 输出。哎呀!
del /Q /F /S "D:\Shared\Temp\*.*" 2>&1 1>nul | findstr "^" >nul && echo Take action because one or more files were locked and could not be deleted
此解决方案更好,因为它直接检测 DEL 的错误。如果文件在锁定检查之后但在删除之前被锁定,则作为单独的命令查找锁定的文件可能会失败。