使用上下文菜单项以管理员身份运行启动批处理文件时,哪个目录是当前工作目录取决于当前用户的用户帐户控制 (UAC)设置。
这可以通过以下小批量文件C:\Temp\Test.bat来演示:
@echo Current directory is: %CD%
@pause
在用户帐户控制设置
中选择
默认 - 仅当程序尝试更改我的计算机时通知我
并且使用 以管理员身份运行,Windows 使用注册表项
HKEY_CLASSES_ROOT\batfile\shell\runasuser\command
此注册表项不包含用于执行批处理文件的默认字符串。取而代之的是字符串值DelegateExecute,CLSID 为{ea72d00e-4960-42fa-ba92-7792a7944c1d}。
结果是打开一个对话框窗口,标题为用户帐户控制和文本:
您要允许以下程序对此计算机进行更改吗?
程序名称:Windows 命令处理器
已验证发布者:Microsoft Windows
在用户确认后,Windows 会临时打开一个新的用户会话,就像在命令行上使用 RunAs 时一样。
在这个新用户会话中,当前工作目录是%SystemRoot%\System32,现在执行 Windows 注册表中定义的命令,默认字符串为密钥
HKEY_CLASSES_ROOT\batfile\shell\runas\command
这是:
%SystemRoot%\System32\cmd.exe /C "%1" %*
因此打开一个控制台窗口,标题为 C:\Windows\System32\cmd.exe 和两行:
Current directory is: C:\Windows\System32
Press any key to continue . . .
按任意键后,批处理执行完成,导致关闭cmd.exe,从而关闭用户会话。
但是在用户帐户控制设置
中进行了选择
从不通知我
程序尝试安装软件或对我的计算机进行更改
我对 Windows 设置进行了更改
行为有所不同,因为用户已经提升了权限。
现在 Windows 直接使用命令
%SystemRoot%\System32\cmd.exe /C "%1" %*
根据key的默认字符串
HKEY_CLASSES_ROOT\batfile\shell\runas\command
在当前用户会话中。
结果是打开一个标题为C:\Windows\System32\cmd.exe的控制台窗口,但在窗口中显示的是:
Current directory is: C:\Temp
Press any key to continue . . .
父进程的当前工作目录(Windows Explorer 作为桌面)用于执行批处理文件,因为在这种情况下不需要切换到不同的用户会话。
PA 在他的回答中已经发布了 2 个可能的解决方案,我在这里复制了一个小的改进(pushd,目录用双引号括起来)并添加了第三个。
-
使用 pushd 和 popd 将当前目录更改为批处理文件的目录:
pushd "%~dp0"
%SystemRoot%\System32\xcopy.exe "File1.txt" "File2.txt" /Y
popd
这也适用于 UNC 路径。在命令提示符窗口pushd /? 中运行以解释为什么这也适用于 UNC 路径。
-
在源和目标规范中使用批处理文件的目录:
%SystemRoot%\System32\xcopy.exe "%~dp0File1.txt" "%~dp0File2.txt" /Y
-
使用 cd 将工作目录更改为批处理文件的目录:
cd /D "%~dp0"
%SystemRoot%\System32\xcopy.exe "File1.txt" "File2.txt" /Y
这不适用于 UNC 路径,因为默认情况下命令解释器 cmd 不支持将 UNC 路径作为当前目录,请参阅例如 CMD does not support UNC paths as current directories 了解详细信息。