从外部文件中读取变量无法按计划任务处理 运行

Read variable from external file not working on running as scheduled task

我想 运行 在 Windows 中从睡眠状态恢复后的批处理文件。

如果我在命令行上启动批处理文件,一切都会按预期进行。

但是批处理脚本没有运行作为预定任务正常执行。

我做了什么:

外部配置文件 AutoMountConf.bat 包含 set Pass = Test

本地脚本文件scheduleTask.bat包含

rem AutoMountConf.bat is in my intranet.
call  X:\AutoMountConf.bat
start "" "C:\Program Files\TrueCrypt\TrueCrypt.exe" /auto favorites /p %Pass% /q

在命令行上安装了 TrueCrypt 容器。 如果我 运行 来自计划任务的脚本,我会在登录屏幕上手动输入密码。

set Pass = Test

设置一个变量pass<space>,内容为<space>Test。所以 %pass% 保持为空。

使用此语法:

set "Pass=Test"

避免任何意外的空格。

有两个甚至三个问题。

第一个是 set Pass = Test 而不是 set "Pass=Test" 作为 Stephan reported already. For more details on how to assign a value right to an environment variable see my answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line?


第二个问题是由于网络驱动器一旦被用户映射到驱动器号并被 Windows 记住在注册表中,在用户注销时被 Windows 自动断开连接并且是仅当同一用户再次登录时才重新连接。

因此,对于计划任务,通常需要对网络共享文件夹中的文件和文件夹使用 UNC 路径,或者连接网络驱动器并在作为计划任务执行的批处理文件本身中断开连接。

无法调用具有 UNC 路径的批处理文件。 Windows 不允许这样做。因此有必要在批处理文件中手动连接和断开网络共享。我为这个问题提供了 2 种解决方案。

第一个是使用命令 net use:

%SystemRoot%\System32\net.exe use X: \ComputerName\ShareName password /user:Domain\UserName /persistent:no
if not errorlevel 1 (
    call X:\AutoMountConf.bat
    %SystemRoot%\System32\net.exe use X: /delete
    start "" /wait "C:\Program Files\TrueCrypt\TrueCrypt.exe" /auto favorites /p %Pass% /q
)

password/user:Domain\UserName 仅当计划任务未使用有权访问远程计算机上的批处理文件的用户帐户执行时才需要。通常,使用正确的用户帐户定义计划任务并确保该帐户的密码与任务一起安全要安全得多。 Windows 存储加密任务的密码,就像它对用户帐户本身一样。

运行 在命令提示符 windows net use /? 中获取有关必需选项和可选选项的详细信息。 /persistent:no 避免记住 Windows 注册表中的网络共享,以便同一用户登录后自动重新连接。

第二个是使用命令 pushdpopd:

pushd \ComputerName\ShareName
if not errorlevel 1 (
    call AutoMountConf.bat
    popd
    start "" /wait "C:\Program Files\TrueCrypt\TrueCrypt.exe" /auto favorites /p %Pass% /q
)

请在命令提示符下执行 window pushd /? 并阅读输出帮助以了解其工作原理。

但此解决方案要求用于计划任务且密码正确的用户帐户是对远程计算机上的共享具有适当权限的用户帐户。此解决方案无法在批处理文件本身中指定密码和用户名。

if not errorlevel 1 表示如果先前的命令退出时没有大于或等于 1 的值表示如果先前命令的退出代码为 0 则命令执行成功。远程机器当前在网络上不可用的情况总是会发生,因此最好检查连接是否成功以在远程机器上共享。


Pass 未在 运行 AutoMountConf.bat 之后定义的原因可能还有一个。

AutoMountConf.bat 包含 setlocal 并且变量 Pass 是在执行此命令之后和 endlocal 之前定义的在同一个批处理文件中执行或在退出 AutoMountConf.bat.

时由命令处理器隐式调用

setlocal 导致始终创建现有环境变量的 copy,并且对环境变量的所有修改都在这个本地副本上完成。以前的环境变量在执行(匹配)endlocal 时或批处理文件结束时恢复,在这种情况下,命令处理器会自动恢复以前的环境。

请在命令提示符下执行 window setlocal /? 并阅读输出帮助。

有关通过命令 setlocalendlocal 了解环境管理的示例,也许甚至更好地查看 Echoing a URL in Batch and [=28 上的答案=]