Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 双击而不是从控制台窗口运行时暂停批处理文件?_Windows_Batch File - Fatal编程技术网

Windows 双击而不是从控制台窗口运行时暂停批处理文件?

Windows 双击而不是从控制台窗口运行时暂停批处理文件?,windows,batch-file,Windows,Batch File,批处理文件(在本例中,在Windows XP上运行)是否有办法确定它是从命令行(即控制台窗口内)启动的,还是通过shell启动的(例如双击) 我有一个脚本,我希望在通过shell运行时在某些点暂停,但在命令行上运行时不暂停。我已经看到了,但我无法使用相同的解决方案,原因有两个:第一,它是否暂停需要取决于多个因素,其中只有一个因素是它是否被双击。第二,我将把这个脚本分发给我团队中的其他人,我不能实际要求他们对注册表进行更改,这将影响所有脚本 这可能吗?一种方法可能是在c:\的根目录中创建一个aut

批处理文件(在本例中,在Windows XP上运行)是否有办法确定它是从命令行(即控制台窗口内)启动的,还是通过shell启动的(例如双击)

我有一个脚本,我希望在通过shell运行时在某些点暂停,但在命令行上运行时不暂停。我已经看到了,但我无法使用相同的解决方案,原因有两个:第一,它是否暂停需要取决于多个因素,其中只有一个因素是它是否被双击。第二,我将把这个脚本分发给我团队中的其他人,我不能实际要求他们对注册表进行更改,这将影响所有脚本


这可能吗?

一种方法可能是在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
  • 变量“testl”获取cmd处理器调用的完整行,去掉所有讨厌的双引号
  • 变量“testr”接受“testl”,并进一步去掉当前批处理文件名的名称(如果双击批处理文件调用,则为当前批处理文件名)
  • if语句查看“testl”和“testr”是否不同。如果是,则双击批次,因此暂停;如果否,则批处理是在命令行中键入的(或从另一个批处理文件调用的),请继续

  • 编辑:可以在一行中完成相同的操作:

    echo %cmdcmdline% | findstr /i /c:"%~nx0" && set standalone=1
    
    用简单的英语来说,这个

    • 通过管道将
      %cmdline%
      的值传递给findstr,然后findstr搜索当前脚本名称
    • %0
      包含当前脚本名称,当然只有在事先未调用
      shift
      时才包含
    • %~nx0
      %0
    • >NUL2>&1
      通过将任何输出重定向到NUL来禁用findstr
    • 如果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-你说得对;