确定批处理脚本是否已从命令行 (cmd) 启动/执行 - 或 - 暂停还是不暂停?

发布于 2025-01-08 18:54:08 字数 365 浏览 1 评论 0原文

我喜欢在我的 cmd.exe 脚本中使用典型的“usage:”行 - 如果缺少参数,系统会简单提醒用户如何使用该脚本。

问题是我无法安全地预测潜在用户是否会使用 GUI 还是 CLI。如果使用 GUI 的人在资源管理器窗口中双击此脚本,他们将没有机会读取任何内容,除非我暂停窗口。如果他们使用 CLI,暂停 会打扰他们。

所以我正在寻找一种方法来检测它。

@echo off
if _%1_==__ (
    echo usage: %nx0: filename
    rem now pause or not to pause?
)

这方面有好的解决办法吗?

I like to have a typical "usage:" line in my cmd.exe scripts — if a parameter is missing, user is given simple reminder of how the script is to be used.

The problem is that I can't safely predict whether potential user would use GUI or CLI. If somebody using GUI double-clicks this script in Explorer window, they won't have chance to read anything, unless I pause the window. If they use CLI, pause will bother them.

So I'm looking for a way to detect it.

@echo off
if _%1_==__ (
    echo usage: %nx0: filename
    rem now pause or not to pause?
)

Is there a nice solution on this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

べ繥欢鉨o。 2025-01-15 18:54:08

您可以检查 %CMDCMDLINE% 变量的值。它包含用于启动 cmd.exe 的命令。

我准备了一个测试 .bat 文件:

@Echo Off
echo %CMDCMDLINE%
pause

当从打开的 cmd.exe 窗口内部运行时,脚本会打印 "C:\Windows\system32\cmd.exe"
通过双击运行时,它会打印 cmd /c ""C:\Users\mbu\Desktop\test.bat" "

因此,要检查脚本是否通过双击启动,您需要检查 %cmdcmdline% 是否包含脚本的路径。最终的解决方案如下所示:

@echo off

set interactive=1
echo %cmdcmdline% | find /i "%~0" >nul
if not errorlevel 1 set interactive=0

rem now I can use %interactive% anywhere

if _%1_==__ (
    echo usage: %~nx0 filename
    if _%interactive%_==_0_ pause
)

编辑:针对评论中讨论的问题更改实施了修复;编辑示例来演示它们

You can check the value of %CMDCMDLINE% variable. It contains the command that was used to launch cmd.exe.

I prepared a test .bat file:

@Echo Off
echo %CMDCMDLINE%
pause

When run from inside of open cmd.exe window, the script prints "C:\Windows\system32\cmd.exe".
When run by double-clicking, it prints cmd /c ""C:\Users\mbu\Desktop\test.bat" "

So to check if your script was launched by double-clicking you need to check if %cmdcmdline% contains the path to your script. The final solution would look like this:

@echo off

set interactive=1
echo %cmdcmdline% | find /i "%~0" >nul
if not errorlevel 1 set interactive=0

rem now I can use %interactive% anywhere

if _%1_==__ (
    echo usage: %~nx0 filename
    if _%interactive%_==_0_ pause
)

Edit: implemented fixes for issues changes discussed in comments; edited example to demonstrate them

香草可樂 2025-01-15 18:54:08
:: exit if not interactive
echo %CMDCMDLINE% | find /i "/c"
if not ERRORLEVEL 1 goto:eof
:: exit if not interactive
echo %CMDCMDLINE% | find /i "/c"
if not ERRORLEVEL 1 goto:eof
我ぃ本無心為│何有愛 2025-01-15 18:54:08

在这里,我写了一些东西...

Usage.bat


@echo off
if arg%1==arg goto help
goto action

:action
echo do something...
goto end

:help
set help1=This is Help line 1.
set help2=This is Help line 2.
cmd.exe /k "echo %help1% &echo %help2%"
goto end

:end

它并不完美,但它有效! :D-

乔德夫

Here, I wrote something...

Usage.bat


@echo off
if arg%1==arg goto help
goto action

:action
echo do something...
goto end

:help
set help1=This is Help line 1.
set help2=This is Help line 2.
cmd.exe /k "echo %help1% &echo %help2%"
goto end

:end

It's not perfect, but it works! :D

-joedf

凉薄对峙 2025-01-15 18:54:08

这仅使用内部命令。如此有效....

启用延迟扩展

if "!cmdcmdline!" neq "!cmdcmdline:%~f0=!" pause >nul

if not "!cmdcmdline!" == "!cmdcmdline:%~f0=!" pause >nul

禁用延迟扩展

if "%cmdcmdline%" neq "%cmdcmdline:%~f0=%" pause >nul

if not "%cmdcmdline%" == "%cmdcmdline:%~f0=%" pause >nul

This is only using the internal command. so effectively....

EnableDelayedExpansion

if "!cmdcmdline!" neq "!cmdcmdline:%~f0=!" pause >nul

or

if not "!cmdcmdline!" == "!cmdcmdline:%~f0=!" pause >nul

DisableDelayedExpansion

if "%cmdcmdline%" neq "%cmdcmdline:%~f0=%" pause >nul

or

if not "%cmdcmdline%" == "%cmdcmdline:%~f0=%" pause >nul
﹎☆浅夏丿初晴 2025-01-15 18:54:08

开始批量检查 %cmdcmdline% 中的 %WINDIR%,如下所示:

echo "%cmdcmdline%" | findstr /ic:"%windir%" >nul && (
  echo Interactive run of: %0 is not allowed
  pause
  exit /B 1
)

Start your batch checking for %WINDIR% in %cmdcmdline% like this:

echo "%cmdcmdline%" | findstr /ic:"%windir%" >nul && (
  echo Interactive run of: %0 is not allowed
  pause
  exit /B 1
)
池予 2025-01-15 18:54:08

请使用 findstr

echo %cmdcmdline% | findstr /ic:"%~f0" >nul && ( pause >nul )

setlocal EnableDelayedExpansion
.
.
echo !cmdcmdline! | findstr /ic:"%~f0" >nul && ( pause >nul )
.
.
endlocal

这始终有效...

Please use findstr

echo %cmdcmdline% | findstr /ic:"%~f0" >nul && ( pause >nul )

or

setlocal EnableDelayedExpansion
.
.
echo !cmdcmdline! | findstr /ic:"%~f0" >nul && ( pause >nul )
.
.
endlocal

This is always worked...

幽蝶幻影 2025-01-15 18:54:08

对于内部命令

setlocal EnableDelayedExpansion
set "cmddiff=!cmdcmdline:~0,1!" & if !cmddiff! neq ^" ( pause >nul )
endlocal

setlocal EnableDelayedExpansion
set "cmddiff=!cmdcmdline:~28,1!" & if !cmddiff! neq ^" ( pause >nul )
endlocal

您可以比较不同的东西,但这仅在 EnableDelayedExpansion 中有效。而且我不认为这总是有效,因为 Windows 版本等等......

for internal command

setlocal EnableDelayedExpansion
set "cmddiff=!cmdcmdline:~0,1!" & if !cmddiff! neq ^" ( pause >nul )
endlocal

or

setlocal EnableDelayedExpansion
set "cmddiff=!cmdcmdline:~28,1!" & if !cmddiff! neq ^" ( pause >nul )
endlocal

You can compare the different thing, but this is only worked within EnableDelayedExpansion. and I don't think that this will be always worked, cause windows version, etc...

尸血腥色 2025-01-15 18:54:08

类似的做法...

setlocal

set startedFromExplorer=
echo %cmdcmdline% | find /i "cmd.exe /c """"%~0""" >nul
if not errorlevel 1 set startedFromExplorer=1

...

if defined startedFromExplorer pause
goto :EOF

Similar approach...

setlocal

set startedFromExplorer=
echo %cmdcmdline% | find /i "cmd.exe /c """"%~0""" >nul
if not errorlevel 1 set startedFromExplorer=1

...

if defined startedFromExplorer pause
goto :EOF
墨小墨 2025-01-15 18:54:08
setlocal EnableDelayedExpansion

if "!cmdcmdline!" neq "!cmdcmdline:%comspec%=!" ( pause>nul )

测试是在Windows 10中完成的。使用%windir%,它有点危险或不明确。所以 %comspec% 是超级安全的。

setlocal EnableDelayedExpansion

if "!cmdcmdline!" neq "!cmdcmdline:%comspec%=!" ( pause>nul )

Test is done in Windows 10. Using %windir%, it is a little dangerous or ambiguous. So %comspec% is super safe.

杀手六號 2025-01-15 18:54:08

这仅对带有复制和行的逐行输入有效。粘贴批处理程序。当我检测到我将剪贴板复制到 %temp% 文件夹中的 cmd 文件中并要求用户从那里执行该文件时:

set %cmdfile%=%temp%\somecmdfile.cmd

if "%~0" == %0 goto :batch

powershell -c get-clipboard>%cmdfile%

powershell -c "Set-Clipboard -Value '%cmdfile%'"

cls

@echo Please start %cmdfile% manually by pasting to Run (it's in clipboard)

pause

:batch 

This is valid only for a line by line entry with copy & paste of a batch program. When I detect that I copy the clipboard into a cmd file in the %temp% folder and ask the user to execute the file from there:

set %cmdfile%=%temp%\somecmdfile.cmd

if "%~0" == %0 goto :batch

powershell -c get-clipboard>%cmdfile%

powershell -c "Set-Clipboard -Value '%cmdfile%'"

cls

@echo Please start %cmdfile% manually by pasting to Run (it's in clipboard)

pause

:batch 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文