我有一个bat文件可以执行大量操作并关闭cmd窗口,当用户从资源管理器中双击bat文件时这很好。但是,如果我从cmd> c:\ myfile.bat中已经打开的cmd窗口运行bat文件,那么我不希望bat文件关闭cmd窗口(END),因为我需要做其他事情。我需要bat dos命令代码,它将执行类似
的操作if (initiated_from_explorer) then
else
endif
这可能吗?感谢
答案 0 :(得分:13)
%cmdcmdline%
给出了用于启动当前Cmd.exe的确切命令行。
"%SystemRoot%\system32\cmd.exe"
。cmd /c ""{full_path_to_the_bat_file}" "
; %0
变量,对于,在这种情况下它始终是bat文件的完整路径,并且始终用双引号括起来。就个人而言,我会采用%cmdcmdline%
方法(而不是%O
),但要注意两个启动命令都可以在注册表中重写...
答案 1 :(得分:13)
来自“mousio”的解决方案很好;但是,由于%cmdcmdline%
的值为双引号(在%cmdcmdline%
附近有或没有双引号),我个人无法在“IF”语句中使其工作。
但是,使用%0
的解决方案可以正常工作。我使用了以下块语句,它就像一个魅力:
IF %0 == "%~0" pause
如果以前的解决方案没有(Alex Essilfie的礼貌),以下解决方案也可能有效:
IF %0 EQU "%~dpnx0" PAUSE
希望它可以提供帮助。
答案 2 :(得分:5)
综合答案,源自此页面上的大部分信息:
:pauseIfDoubleClicked
setlocal enabledelayedexpansion
set testl=%cmdcmdline:"=%
set testr=!testl:%~nx0=!
if not "%testl%" == "%testr%" pause
当然,如果你想检测双击,你可以做其他事情,你可以改变暂停。
谢谢大家。
答案 3 :(得分:3)
您可以在从CMD窗口运行时添加命令行参数,该窗口在双击文件时不存在。如果没有参数,请关闭窗口。如果有,请不要关闭它。您可以使用%1
答案 4 :(得分:2)
这不仅可行,而且您希望的行为是批处理文件执行的正常行为,除非您执行“特殊”操作:
所以我认为需要回答的问题是你在批处理文件中做了什么导致命令窗口在命令行执行时关闭?
答案 5 :(得分:2)
使用exit /b 0
,而不是exit
如果从Windows资源管理器启动,前者将一直退出,但如果从命令行启动,则返回控制台。
答案 6 :(得分:2)
在其他答案的基础上,我找到了最可靠的方法:
x
替换引号以启用文本比较而不会破坏IF语句。x
替换为“”)。set "dclickcmdx=%systemroot%\system32\cmd.exe /c xx%~0x x"
set "actualcmdx=%cmdcmdline:"=x%"
set isdoubleclicked=0
if /I "%dclickcmdx%" EQU "%actualcmdx%" (
set isdoubleclicked=1
)
这增加了针对常规cmd /c
调用的稳定性,因为资源管理器在最后一个引号/ x之前添加了一个尴尬的额外空间(对我们有利)。如果找不到cmdcmdline
,它将正确呈现isdoubleclicked=0
。
答案 7 :(得分:1)
与@anishsane一样,如果从资源管理器启动,我也想要一个暂停语句,但是从命令窗口启动时却不需要。
根据@ mousio上面的回答,这对我有用:
@SET cmdcmdline|FINDSTR /b "cmdcmdline="|FINDSTR /i pushd >nul
@IF ERRORLEVEL 1 (
@echo.
@echo Press ENTER when done
@pause > nul
)
(这里没有任何原创,仅提供一个工作示例)
答案 8 :(得分:0)
将其粘贴在BAT或CMD脚本的开头,并可能更改“if”子句中发生的情况:
:: To leave command window open if script run from Windows explorer.
@setlocal
@set x=%cmdcmdline:"=%
@set x=%x: =%
@set y=%x:cmd/c=%
@if "%x%" neq "%y%" cmd /k %0 %* && exit || exit
@endlocal
这样做,如果用户双击或使用“cmd / c”调用此脚本,它将使用“cmd / k”重新启动,这将在命令完成后使会话保持打开状态。这允许用户退出或者做其他事情。
这样做的原因而不是在这个答案中解释的其他方式是因为我发现情况仍然使用引号或其他符号,IF语句会在某些情况下使用QUOTES和/ c和空格。所以逻辑首先删除所有QUOTES,然后删除所有空格..因为删除引号后有一些额外的空格。
set x=%cmdcmdline:"=% <-- removes all quotes
set x=%x: =% <-- removes all spaces
set y=%x:cmd/c=% <-- removes cmd/c from the string saving it to y
&amp;&amp;&amp;退出|| exit是这样的,如果退出前的ERRORLEVEL为0(成功),则它会停止运行,但如果它不为0(某些失败),它也会停止运行。
但你可以替换这部分:
cmd /k %0 %* && exit || exit
类似
set CALLED_WITH_CMD_C=YES
然后在脚本的其余部分中弥补自己的差异。然后你必须移动或删除endlocal。
前面的'@'符号可以防止回声,如果你想测试,你可以拥有回声。 不要使用echo on或echo off,因为它会更改设置并影响调用你的所有后续脚本。
答案 9 :(得分:0)
@dlchambers很接近但是没有设置,因为cmdcmdline在某些情况下不是一个定义的环境变量,但这个版本基于他的作品对我很有用:
echo %cmdcmdline% | findstr /i pushd >nul
if errorlevel 1 pause
答案 10 :(得分:0)
set __cmdcmdline=%cmdcmdline%
set __cmdcmdline=%__cmdcmdline:"=%
set __cmdcmdline=%__cmdcmdline: =%
set __cmdcmdline=%__cmdcmdline:~0,5%
if "%__cmdcmdline%"=="cmd/c" set CMD_INITIATED_FROM_EXPLORER=1
set __cmdcmdline=
有条件地设置变量:CMD_INITIATED_FROM_EXPLORER
..随后可以根据需要使用:
if defined CMD_INITIATED_FROM_EXPLORER (
echo.
pause
)
..但是@Ruben Bartelink提到的关于Powershell的问题没有解决:
从Powershell运行
./batch.cmd
使用引擎盖下的cmd /c
答案 11 :(得分:0)
您还可以检查SESSIONNAME
环境变量。
正如您在此处看到的那样,通常不会在资源管理器窗口中设置变量。从cmd调用时,它的SESSIONNAME
设置为Console
。我可以在Windows 10上确认这一点。
不幸的是,行为似乎可以改变:https://support.microsoft.com/de-de/help/2509192/clientname-and-sessionname-enviroment-variable-may-be-missing