Windows 双击而不是从控制台窗口运行时暂停批处理文件?
批处理文件(在本例中,在Windows XP上运行)是否有办法确定它是从命令行(即控制台窗口内)启动的,还是通过shell启动的(例如双击) 我有一个脚本,我希望在通过shell运行时在某些点暂停,但在命令行上运行时不暂停。我已经看到了,但我无法使用相同的解决方案,原因有两个:第一,它是否暂停需要取决于多个因素,其中只有一个因素是它是否被双击。第二,我将把这个脚本分发给我团队中的其他人,我不能实际要求他们对注册表进行更改,这将影响所有脚本Windows 双击而不是从控制台窗口运行时暂停批处理文件?,windows,batch-file,Windows,Batch File,批处理文件(在本例中,在Windows XP上运行)是否有办法确定它是从命令行(即控制台窗口内)启动的,还是通过shell启动的(例如双击) 我有一个脚本,我希望在通过shell运行时在某些点暂停,但在命令行上运行时不暂停。我已经看到了,但我无法使用相同的解决方案,原因有两个:第一,它是否暂停需要取决于多个因素,其中只有一个因素是它是否被双击。第二,我将把这个脚本分发给我团队中的其他人,我不能实际要求他们对注册表进行更改,这将影响所有脚本 这可能吗?一种方法可能是在c:\的根目录中创建一个aut
这可能吗?一种方法可能是在c:\的根目录中创建一个autoexec.nt文件,看起来像:
@set nested=%nested%Z
在批处理文件中,检查%nested%是否为“Z”-如果为“Z”,则表示双击了您,请暂停。如果它不是“Z”-它将是“ZZ”或“ZZZ”等,因为CMD继承父进程的环境块
-Oisin找到了一个:-)-在拼命思考了当以交互方式运行时,而不是直接启动批处理文件时,cmd
可能会做什么之后。。。我终于找到了一个
伪变量%cmdline%
包含用于启动cmd
的命令行。如果cmd
正常启动,则包含类似以下内容:
"C:\Windows\System32\cmd.exe"
但是,启动批处理文件时,如下所示:
cmd /c ""C:\Users\Me\test.cmd" "
小型演示:
@echo off
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set DOUBLECLICKED=1
if defined DOUBLECLICKED pause
不过,这种检查方法可能不是最可靠的,但只有在直接启动批处理文件时,/c
才应作为参数出现
在Windows 7 x64上测试。它可能起作用,也可能不起作用,可能会断裂,可能会做一些奇怪的事情,吃孩子(可能是件好事),或者咬你的鼻子。更多信息 我从一个批处理文件(test.cmd)开始,该文件包含:
@echo %cmdcmdline%
如果在Windows资源管理器中双击“test.cmd”批处理文件,则echo%cmdline%的显示为:
cmd /c ""D:\Path\test.cmd" "
"C:\Windows\system32\cmd.exe"
"C:\Windows\System32\cmd.exe" /k ver
在命令提示窗口内执行“test.cmd”批处理文件时,显示echo%cmdline%取决于命令窗口的启动方式 如果我通过单击“启动Orb”和“命令提示符”启动“cmd.exe”,或者如果我单击“启动Orb”并从搜索/运行框执行“cmd.exe”。然后执行“test.cmd”批处理文件,echo%cmdline%的显示为:
cmd /c ""D:\Path\test.cmd" "
"C:\Windows\system32\cmd.exe"
"C:\Windows\System32\cmd.exe" /k ver
另外,对于我来说,如果我从桌面快捷方式中单击“命令提示符”,然后执行“test.cmd”批处理文件,则echo%cmdline%的显示也会:
"C:\Windows\system32\cmd.exe"
但是,如果我在Windows资源管理器窗口中“右键单击”并选择“在此处打开命令提示符”,然后执行“test.cmd”批处理文件,则echo%cmdline%的显示为:
cmd /c ""D:\Path\test.cmd" "
"C:\Windows\system32\cmd.exe"
"C:\Windows\System32\cmd.exe" /k ver
因此,请注意,如果您从“Target”字段中包含“/c”的快捷方式启动“cmd.exe”(不太可能),那么上一个示例中的测试将无法正确测试此情况。一个综合答案,来自此页面上的大部分信息(以及其他一些具有类似问题的堆栈溢出页面)。这并不依赖于检测/c,而是在命令行中实际检查脚本的名称。因此,如果双击另一批,然后调用此批,此解决方案将不会暂停;您必须双击这个特定的批处理文件
:pauseIfDoubleClicked
setlocal enabledelayedexpansion
set testl=%cmdcmdline:"=%
set testr=!testl:%~nx0=!
if not "%testl%" == "%testr%" pause
编辑:可以在一行中完成相同的操作:
echo %cmdcmdline% | findstr /i /c:"%~nx0" && set standalone=1
用简单的英语来说,这个
- 通过管道将
的值传递给findstr,然后findstr搜索当前脚本名称%cmdline%
包含当前脚本名称,当然只有在事先未调用%0
时才包含shift
从%~nx0
%0
通过将任何输出重定向到NUL来禁用findstr>NUL2>&1
- 如果findstr找不到有问题的子字符串,它将设置一个非零errorlevel
仅在前面的命令返回时无错误时执行&&
- 因此,如果脚本是从命令行启动的,则不会定义独立脚本
if defined standalone pause
这个主意很有趣,但似乎不管用
AUTOEXEC.NT
似乎被完全忽略,AUTOEXEC.BAT
只执行一次(在系统启动时),并且每个CMD.EXE
会话都会执行一次自动运行注册表项,无论它是如何启动的。批处理文件不会在新的CMD
进程中启动。因此,如果我只是启动一个cmd
实例并从那里启动批处理文件,nested
将是Z
。另外,检测嵌套shell是一个不错的主意,但不适用于批处理文件。另一个注意事项:autoexec.nt
从不位于驱动器的根目录中,而是位于%systemroot%\system32
中。据我所知,它只会影响command.com
,而不会影响cmd
,当然。有时候,把你的想法发布出来,希望它能触发别人的脑波是值得的,而另一个答案并不意味着注册表会发生变化。仅更改在快捷方式上执行的命令行。当然,如果你双击实际的批处理文件,这对你没有多大帮助。@Joey-你说得对;