windows 双击时暂停批处理文件而不是从控制台窗口运行时暂停?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3551888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pausing a batch file when double-clicked but not when run from a console window?
提问by Ben Blank
Is there a way for a batch file (in this case, running on Windows XP) to determine whether it was launched from a command line (i.e. inside a console window) or launched via the shell (e.g. by double-clicking)?
有没有办法让批处理文件(在这种情况下,在 Windows XP 上运行)确定它是从命令行启动(即在控制台窗口内)还是通过外壳启动(例如通过双击)?
I have a script which I'd like to have pause at certain points when run via the shell, but not when run at a command line. I've seen a similar questionon SO, but am unable to use the same solution for two reasons: first, whether or not it pauses needs to be dependent on multiple factors, only one of which is whether it was double-clicked. Second, I'll be distributing this script to others on my team and I can't realistically ask all of them to make registry changes which will affect all scripts.
我有一个脚本,我希望在通过 shell 运行时在某些点暂停,但在命令行上运行时不暂停。我在 SO 上看到了一个类似的问题,但是由于两个原因我无法使用相同的解决方案:首先,它是否暂停需要取决于多个因素,其中一个是它是否被双击。其次,我将把这个脚本分发给我团队中的其他人,我不能现实地要求他们所有人进行会影响所有脚本的注册表更改。
Is this possible?
这可能吗?
回答by Joey
Found one :-) – After desperately thinking of what cmd
might do when run interactively but not when launching a batch file directly ... I finally found one.
找到一个 :-) – 在拼命思考cmd
交互运行时可能会做什么之后,而不是直接启动批处理文件时......我终于找到了一个。
The pseudo-variable %cmdcmdline%
contains the command line that was used to launch cmd
. In case cmd
was started normally this contains something akin to the following:
伪变量%cmdcmdline%
包含用于启动cmd
. 如果cmd
正常启动,它包含类似于以下内容的内容:
"C:\Windows\System32\cmd.exe"
However, when launching a batch file it looks like this:
但是,当启动批处理文件时,它看起来像这样:
cmd /c ""C:\Users\Me\test.cmd" "
Small demo:
小演示:
@echo off
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set DOUBLECLICKED=1
if defined DOUBLECLICKED pause
This way of checking might not be the most robust, though, but /c
should only be present as an argument if a batch file was launched directly.
不过,这种检查方式可能不是最可靠的,但/c
仅当直接启动批处理文件时才应作为参数出现。
Tested here on Windows 7 x64. It may or may not work, break, do something weird, eat children (might be a good thing) or bite you in the nose.
在 Windows 7 x64 上进行了测试。它可能会也可能不会起作用,打破,做一些奇怪的事情,吃孩子(可能是一件好事)或咬你的鼻子。
回答by DocOc
A consolidated answer, derived from much of the information found on this page (and some other stack overflow pages with similar questions). This one does not rely on detecting /c, but actually checks for the name of the script in the command line. As a result this solution will not pause if you double-clicked on another batch and then called this one; you had to double-click on this particular batch file.
一个综合的答案,来自这个页面上的大部分信息(以及其他一些具有类似问题的堆栈溢出页面)。这个不依赖检测/c,而是在命令行中实际检查脚本的名称。因此,如果您双击另一个批次然后调用此解决方案,则该解决方案不会暂停;你必须双击这个特定的批处理文件。
:pauseIfDoubleClicked
setlocal enabledelayedexpansion
set testl=%cmdcmdline:"=%
set testr=!testl:%~nx0=!
if not "%testl%" == "%testr%" pause
- The variable "testl" gets the full line of the cmd processor call, stripping out all of the pesky double quotes.
- The variable "testr" takes "testl" and further strips outs the name of the current batch file name if present (which it will be if the batch file was invoked with a double-click).
- The if statement sees if "testl" and "testr" are different. If yes, batch was double-clicked, so pause; if no, batch was typed in on command line (or called from another batch file), go on.
- 变量“testl”获取 cmd 处理器调用的完整行,去掉所有讨厌的双引号。
- 变量“testr”采用“testl”并进一步删除当前批处理文件的名称(如果存在)(如果双击调用批处理文件,它将是)。
- if 语句查看“testl”和“testr”是否不同。如果是,批处理被双击,所以暂停;如果不是,批处理是在命令行中输入的(或从另一个批处理文件调用),继续。
Edit: The same can be done in a single line:
编辑:同样可以在一行中完成:
echo %cmdcmdline% | findstr /i /c:"%~nx0" && set standalone=1
In plain English, this
用简单的英语,这
- pipes the value of
%cmdcmdline%
to findstr, which then searches for the current script name %0
contains the current script name, of course only ifshift
has not been called beforehand%~nx0
extracts file name and extension from%0
>NUL 2>&1
mutes findstrby redirecting any output to NUL- findstrsets a non-zero errorlevel if it can't find the substring in question
&&
only executes if the preceding command returned without error- as a consequence,
standalone
will not be defined if the script was started from the command line
- 将 的值通过管道
%cmdcmdline%
传递给findstr,然后查找当前脚本名称 %0
包含当前脚本名称,当然前提是shift
没有被预先调用%~nx0
从中提取文件名和扩展名%0
>NUL 2>&1
通过将任何输出重定向到 NUL 来静音findstr- 如果 findstr找不到相关子字符串,则它会设置一个非零错误级别
&&
仅当前面的命令没有错误返回时才执行- 因此,
standalone
如果脚本是从命令行启动的,则不会被定义
Later in the script we can do:
稍后在脚本中我们可以执行以下操作:
if defined standalone pause
回答by x0n
One approach might be to create an autoexec.nt file in the root of c:\ that looks something like:
一种方法可能是在 c:\ 的根目录中创建一个 autoexec.nt 文件,如下所示:
@set nested=%nested%Z
In your batch file, check if %nested% is "Z" - if it is "Z" then you've been double-clicked, so pause. If it's not "Z" - its going to be "ZZ" or "ZZZ" etc as CMD inherits the environment block of the parent process.
在您的批处理文件中,检查 %nested% 是否为“Z” - 如果是“Z”,则您已被双击,因此请暂停。如果它不是“Z”——它将是“ZZ”或“ZZZ”等,因为 CMD 继承了父进程的环境块。
-Oisin
-Oisin
回答by Kevin Fegan
A little more information...
多一点信息...
I start with a batch-file (test.cmd) that contains:
我从一个包含以下内容的批处理文件 (test.cmd) 开始:
@echo %cmdcmdline%
If I double-click the "test.cmd" batch-file from within Windows Explorer, the display of echo %cmdcmdline% is:
如果我在 Windows 资源管理器中双击“test.cmd”批处理文件, echo %cmdcmdline% 的显示是:
cmd /c ""D:\Path\test.cmd" "
When executing the "test.cmd" batch-file from within a Command Prompt window, the display of
echo %cmdcmdline% depends on how the command window was started...
从命令提示符窗口中执行“test.cmd”批处理文件时,
echo %cmdcmdline%的显示取决于命令窗口的启动方式...
If I start "cmd.exe" by clicking the "Start-Orb" and "Command Prompt" or if I click "Start-Orb" and execute "cmd.exe" from the search/run box. Then I execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is:
如果我通过单击“Start-Orb”和“命令提示符”启动“cmd.exe”,或者如果我单击“Start-Orb”并从搜索/运行框中执行“cmd.exe”。然后我执行“test.cmd”批处理文件,echo %cmdcmdline% 的显示是:
"C:\Windows\system32\cmd.exe"
Also, for me, if I click "Command Prompt" from the desktop shortcut, then execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is also:
另外,对我来说,如果我从桌面快捷方式中单击“命令提示符”,然后执行“test.cmd”批处理文件,则 echo %cmdcmdline% 的显示也是:
"C:\Windows\system32\cmd.exe"
But, if I "Right-Click" inside a Windows Explorer window and select "Open Command Prompt Here", then execute the "test.cmd" batch-file, the display of echo %cmdcmdline% is:
但是,如果我在 Windows 资源管理器窗口中“右键单击”并选择“在此处打开命令提示符”,然后执行“test.cmd”批处理文件,则 echo %cmdcmdline% 的显示为:
"C:\Windows\System32\cmd.exe" /k ver
So, just be careful, if you start "cmd.exe" from a shortcut that contains a "/c" in the "Target" field (unlikely), then the test in the previous example will fail to test this case properly.
因此,请注意,如果您从“目标”字段中包含“/c”的快捷方式启动“cmd.exe”(不太可能),那么上一个示例中的测试将无法正确测试这种情况。