双击时暂停批处理文件,但从控制台窗口运行时不能暂停?

Ben*_*ank 24 windows batch-file

有没有办法批处理文件(在这种情况下,在Windows XP上运行)来确定它是从命令行启动(即在控制台窗口内)还是通过shell启动(例如通过双击)?

我有一个脚本,我希望在通过shell运行时在某些点暂停,但不是在命令行运行时.我在SO上看到过类似的问题,但由于两个原因我无法使用相同的解决方案:首先,它是否暂停需要依赖于多个因素,其中只有一个是双击.其次,我将把这个脚本分发给我团队中的其他人,我无法真实地要求他们所有人进行注册表更改,这将影响所有脚本.

这可能吗?

Joe*_*oey 35

找到一个:-) - 在拼命思考cmd交互式运行时可能会做什么但在直接启动批处理文件时却没有...我终于找到了一个.

伪变量%cmdcmdline%包含用于启动的命令行cmd.如果cmd通常启动,则包含类似于以下内容的内容:

"C:\Windows\System32\cmd.exe"
Run Code Online (Sandbox Code Playgroud)

但是,在启动批处理文件时,它看起来像这样:

cmd /c ""C:\Users\Me\test.cmd" "
Run Code Online (Sandbox Code Playgroud)

小演示:

@echo off
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set DOUBLECLICKED=1
if defined DOUBLECLICKED pause
Run Code Online (Sandbox Code Playgroud)

但是,这种检查方式可能不是最强大的,但/c如果直接启动批处理文件,则应仅作为参数出现.

在我的机器上工作http://hypftier.de/dump/works_on_my_machine.png

在Windows 7 x64上进行了测试.它可能会或可能不会起作用,休息,做一些奇怪的事情,吃孩子(可能是一件好事)或咬你的鼻子.

  • 在我的Windows 7副本中,以管理员身份运行批处理文件会使资源管理器传递一个大写`/ C`作为参数.这将做一个不区分大小写的比较:`for %% x in(%CMDCMDLINE%)do if/I [%% ~x] equ [/ c] pause` (4认同)
  • @Ben:我也想到了'%0`这件事,但遗憾的是它打破了.当我通过`for`运行`%cmdcmdline%`时,批处理的路径和名称被分解为两个标记,因为我的主目录包含空格,命令行有双引号,如上所示可以抛出`for` off .另一种选择可能是使用`echo.%cmdcmdline%| findstr/i/c:"%〜0"> nul 2>&1 &&设置DOUBLECLICKED = 1`(或者可能是`||`,我总是会犯`findstr' `),实际上会搜索`%0`而不是依赖于标记化.如果批次被另一批次调用,它仍然会失败. (2认同)

Doc*_*cOc 9

综合答案,源自此页面上的大部分信息(以及其他一些具有类似问题的堆栈溢出页面).这个不依赖于detect/c,但实际上是在命令行中检查脚本的名称.因此,如果您双击另一个批次然后调用此批处理,此解决方案将不会暂停; 你必须双击这个特定的批处理文件.

:pauseIfDoubleClicked
setlocal enabledelayedexpansion
set testl=%cmdcmdline:"=%
set testr=!testl:%~nx0=!
if not "%testl%" == "%testr%" pause
Run Code Online (Sandbox Code Playgroud)
  1. 变量"testl"获取cmd处理器调用的完整行,删除所有令人讨厌的双引号.
  2. 变量"testr"采用"testl"并进一步删除当前批处理文件名的名称(如果存在,则将通过双击调用批处理文件).
  3. if语句查看"testl"和"testr"是否不同.如果是,则双击批次,暂停; 如果不是,则在命令行输入批处理(或从另一个批处理文件调用),继续.

编辑:同样可以在一行中完成:

echo %cmdcmdline% | findstr /i /c:"%~nx0" && set standalone=1
Run Code Online (Sandbox Code Playgroud)

用简单的英语,这个

  • 将值%cmdcmdline%传递给findstr,然后搜索当前脚本名称
  • %0包含当前脚本名称,当然只有shift事先没有调用过
  • %~nx0 从中提取文件名和扩展名 %0
  • >NUL 2>&1通过将任何输出重定向到NUL来静音findstr
  • 如果找不到相关子字符串,findstr会设置一个非零错误级别
  • && 仅在前面的命令没有错误返回时执行
  • 因此,standalone如果脚本是从命令行启动的,则不会定义

稍后在脚本中我们可以做到:

if defined standalone pause
Run Code Online (Sandbox Code Playgroud)

  • 不错,喜欢单行本!这适用于 Windows 7。如果您不使用“shift”,您甚至可以直接调用 `ECHO %cmdcmdline% | findstr /i /c:"%~nx0" >NUL 2>&1 && PAUSE` 在脚本末尾 - 不需要变量。 (2认同)