通过双击或从cmd窗口检测bat文件是否正在运行

Gul*_*llu 27 windows cmd

我有一个bat文件,可以执行大量操作并关闭cmd窗口,当用户从资源管理器中双击bat文件时,该窗口很好.但是,如果我从cmd> c:\ myfile.bat中已经打开的cmd窗口运行bat文件,那么我不希望bat文件关闭cmd窗口(END),因为我需要做其他事情.我需要bat dos命令代码,它会做类似的事情

if (initiated_from_explorer) then
else
endif
Run Code Online (Sandbox Code Playgroud)

这可能吗 ?谢谢

mou*_*sio 14

%cmdcmdline% 给出用于启动当前Cmd.exe的确切命令行.

  • 从命令控制台启动时,此var是"%SystemRoot%\system32\cmd.exe".
  • 当从资源管理器启动时,这个变量是cmd /c ""{full_path_to_the_bat_file}" ";
    这意味着您还可以检查%0bat文件中的变量,因为在这种情况下,它始终是bat​​文件的完整路径,并且始终用双引号括起来.

就个人而言,我会选择%cmdcmdline%(而不是%O)方法,但请注意,两个启动命令都可以在注册表中重写...


Jea*_* T. 14

来自"mousio"的解决方案很好; 但是,我个人并没有设法使它在"IF"语句中工作,因为值的双引号%cmdcmdline%(带或不带双引号%cmdcmdline%).

但是,使用的解决方案%0工作正常.我使用了以下块语句,它就像一个魅力:

IF %0 == "%~0"  pause
Run Code Online (Sandbox Code Playgroud)

如果以前的解决方案没有(Alex Essilfie的追求),以下解决方案也可能有效:

IF %0 EQU "%~dpnx0" PAUSE
Run Code Online (Sandbox Code Playgroud)

希望它可以提供帮助.


Sim*_*her 8

代码更少,更健壮:

在其他答案的基础上,我找到了最可靠的方法:

  1. 将引号替换为x可在不破坏 IF 语句的情况下启用文本比较。
  2. 准确地重新创建预期的 cmdcmdline (好吧,将 '"' 替换为x)。
  3. 测试不区分大小写的相等性。

结果是:

set "dclickcmdx=%comspec% /c xx%~0x x"
set "actualcmdx=%cmdcmdline:"=x%"

set isdoubleclicked=0
if /I "%dclickcmdx%" EQU "%actualcmdx%" (
    set isdoubleclicked=1
)
Run Code Online (Sandbox Code Playgroud)

这增加了针对一般调用的鲁棒性cmd /c,因为 Explorer 在最后一个 quote/x 之前添加了一个尴尬的额外空格(对我们有利)。如果cmdcmdline没有找到,它会正确呈现isdoubleclicked=0

附录:

与上述方法类似,如果从资源管理器中双击脚本,则以下一行将暂停脚本。我将其添加到脚本末尾以保持命令行窗口打开:

编辑 2022-01-12,修复了此讨论中的引用不匹配问题)

if /i "%comspec% /c ``%~0` `" equ "%cmdcmdline:"=`%" pause
Run Code Online (Sandbox Code Playgroud)
if /i "%comspec% /c %~0 " equ "%cmdcmdline:"=%" pause
Run Code Online (Sandbox Code Playgroud)


Doc*_*cOc 6

综合答案,源自此页面上的大部分信息:

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

当然,如果您在检测到双击时想要执行其他操作,则可以更改暂停.

感谢大家.


小智 5

使用exit /b 0,不exit

如果从 Windows 资源管理器启动,前者将一直退出,但如果从命令行启动,则返回到控制台。