【问题标题】:Batch script fails when run as admin from explorer, but not when run as admin from terminal?从资源管理器以管理员身份运行时批处理脚本失败,但从终端以管理员身份运行时不失败?
【发布时间】:2016-11-17 22:40:57
【问题描述】:

我有一个需要以管理员身份运行的批处理脚本。我将分发给用户,所以如果他们可以从 Windows 资源管理器中运行它是最好的。

不幸的是,从资源管理器运行时它不起作用(右键单击 -> 以管理员身份运行)。从预先存在的管理终端调用时,它确实有效。

最初我认为问题出在活动目录上,但我添加了“cd /d %~dp0”作为第一个命令。我通过 echo 确认这会将它们放在同一个目录中,但是从资源管理器运行时仍然失败。

读取与.bat 相同目录中的外部文件时发生故障。从资源管理器运行时,它会拉空字符串。这是示例代码:

rem Make sure active directory is correct (verified that this works)
cd /d %~dp0

rem Load parameters from params.txt
for /f "delims== tokens=1,2" %%G in ("params.txt") do set %%G=%%H

rem Print params (it's a loop so you can read it when running from expl.)
for /l %%a in (1 1 100000) do echo %DST%

然后您只需要确保 params.txt 与 .bat 位于同一目录中并包含“DST=some\directory\name”行

有人知道为什么这不起作用吗?

【问题讨论】:

  • 试过setlocal enabledelayedexpansion 吗? (只是一个疯狂的猜测)
  • 是的,结果相同。 ://
  • 尝试用简单的echo %DST% 替换循环,然后是pause 以保持窗口打开?
  • 这样就简单多了!但是不行,还是不行。
  • 您提到您的 params.txt 文件中有“其他参数”。如果您可以使用正则表达式来识别您要查找的行(或者至少排除有问题的行,如果有的话),您可以尝试类似'type "params.txt"^|findstr /R "="'(代替“params.txt”)。此表达式仅抓取其中包含“=”的行,但显然您可以根据实际内容制作更有用的正则表达式。

标签: batch-file


【解决方案1】:

正如@nephi12 在他的回答中所指出的,如果您的文件名没有空格,您可以删除引号,否则它认为 IN 子句是您要解析的字符串。如果您需要引用文件名,则需要使用 cmets 指出的 USEBACKQ 选项。使用该选项后,您的代码就可以正常工作了。

但我想用你的代码说明一点。如果您的 params.txt 文件的内容是:

"DST=some\directory\name"

那么你的FOR 命令可以是这样的:

for /f "usebackq tokens=1 delims=" %%G in ("params.txt") do set %%G

我不明白您为什么要重复 %dst% 变量 100,000 次?

【讨论】:

  • 谢谢,usebackq 修复了它。奇怪的是,这个问题只发生在从文件资源管理器运行时……至于 params 文件,它还包含其他参数,这就是我使用更复杂的读取命令的原因。并且回显处于循环中,因为我不知道“暂停”命令。
  • @user258887,非常怀疑它的行为是否不同。很可能是你正在做的事情。如果您阅读了FOR 命令的帮助,就会很清楚引用内容时会发生什么。
  • 实际上是从命令行运行的,试了几十次,又试了一次。 bat 文件没有参数,所以我不能做不同的事情——我只是导航到目录并输入它的名称。
  • @user258887,很抱歉,但这是不正确的。无论您是直接从命令行运行、从命令行运行批处理文件还是用鼠标双击批处理文件,原始代码行都将以相同的方式执行。
  • 我的意思是,我理解你为什么认为理论上不应该发生,但实际发生的事情与你的理论相矛盾,并且重复了几十次。不幸的是,现实生活中的结果并不总是与理论预测相符。如果我有视频软件,我可以录制并展示给你看,我现在正在一次又一次地测试它。
【解决方案2】:

一方面,去掉 params.txt 周围的 "s,因为双引号表示字符串解析,而未加引号的是文件列表。

其次,尝试在 params.txt 前加上 %~pd0\ 以确保路径正确,而不是更改目录。

【讨论】:

  • 有时,您需要引用文件名(例如,当它包含空格时。在这种情况下,使用for /f "usebackq delims== tokens=1,2" ... - usebackq 选项允许您在文件名周围加上双引号。
  • 感谢 Klitos,只需添加 usebackq 即可解决问题!
猜你喜欢
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 2012-11-22
  • 1970-01-01
相关资源
最近更新 更多