双击时如何使Windows批处理文件暂停?

Sco*_*ham 8 windows batch-file

我写了一个批处理文件来自动执行某些任务.我可以从命令窗口运行它,它运行并显示结果.如果我从资源管理器中双击它,它会立即运行并终止,所以我看不到结果.

有没有办法让批处理文件窗口保持打开状态,直到我解雇它,如果我通过双击图标启动它?

当我从命令行调用批处理文件时,我不想传递/ nopause参数.我想要一个解决方案,我可以使用批处理文件,而不必做任何太特别的事情?

谢谢.

注意我不希望它从命令行运行时暂停!! 我可以从另一个批处理文件中调用此批处理文件来执行一系列操作.在那种情况下,我不能坐在那里继续打击进入.

理想情况下,最好是我可以在批处理文件中放入一些代码,以便它可以解决它从哪里开始,然后暂停或不适当.

Mat*_*hen 14

使用:

cmd /K myBatch.bat
Run Code Online (Sandbox Code Playgroud)

作为你的捷径.

  • 您可以通过修改以下注册表项来实现*all*批处理文件:HKEY_CLASSES_ROOT\batfile\shell\open\command.将值从"%1"%*设置为cmd/k"%1"%* (9认同)

小智 8

我的问题是类似的 - 如果从 Windows 资源管理器调用,我想在最后暂停,但如果在命令窗口中没有暂停。我想出了这个。在每个批处理文件的顶部,放置:

if "%parent%"=="" set parent=%~0
if "%console_mode%"=="" (set console_mode=1& for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" set console_mode=0)
Run Code Online (Sandbox Code Playgroud)

然后在最后

if "%parent%"=="%~0" ( if "%console_mode%"=="0" pause )
Run Code Online (Sandbox Code Playgroud)

它处理嵌套的批处理调用,您只想在原始批处理文件的末尾暂停,而不是在嵌套的批处理文件中暂停。在嵌套的批处理文件中,%parent%已设置为原始调用者,因此它不等于嵌套的%~0. 如果您有bat1which calls bat2,它会打开在资源管理器中双击 bat2 的选项 - 在该上下文bat2中将在结束时暂停,而如果bat1call bat2,则bat2不会在最后bat1暂停(只会暂停)。

&声明分离器有助于避免的东西是次要的主要功能视觉上的混乱。如果您不喜欢它的外观,只需将每个语句放在一个新行上。

此方法将/C作为启动命令 ( %cmdcmdline%)中的参数之一进行查找。它假定您的批处理文件不使用该/C选项。如果你/C自己使用,那么你需要检查是否%COMSPEC%出现在%cmdcmdline%(use FINDSTR) 中。当资源管理器启动一个 bat 文件时,它%cmdcmdline%包括%COMSPEC%例如C:\Windows\System32\cmd.exe /C double_clicked_batch_file_name. 在命令窗口中,%cmdcmdline%只有cmd.exe其中(没有路径)。我使用CALL mybat而不是cmd.exe /C mybat,但您可能必须使用现有的批处理文件。


Kev*_*gan 5

这是一个应该运作良好的解决方案,并考虑到一个批处理文件可能调用另一个批处理文件(“嵌套”)的可能性。

您可以使用Find查找“ / c”,如果从“命令提示符”运行批处理文件,则该“ / c”将不存在:

echo %cmdcmdline% | find /i "/c"
Run Code Online (Sandbox Code Playgroud)

但是,您可以使用“查找”来搜索更长的字符串或批处理文件名称,从而进行更“稳健”的测试。

如果搜索字符串中包含(“)双引号,则” Find“命令将无法正常工作。要解决此问题,您可以使用环境变量替换来“调整”字符串,以便它与Find配合使用:

set newcmdcmdline=%cmdcmdline:"=-%
Run Code Online (Sandbox Code Playgroud)

这通常会返回:

if the batch-file is run from a "Command Prompt"  
    newcmdcmdline=-C:\Windows\system32\cmd.exe-

if the batch-file is run by clicking on the the batch-file  
(or the batch-file shortcut) from "Windows Explorer"  
    newcmdcmdline=cmd /c --D:\Path\test.cmd- -
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用“查找”进行测试,例如:

    echo %newcmdcmdline% | find /i "cmd /c --"
or
    echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"
Run Code Online (Sandbox Code Playgroud)

接下来,您需要确定是否要使“嵌套”批处理文件的行为像执行调用的批处理文件一样,或者是否希望嵌套批处理文件的行为始终像被执行一样从“命令提示符”。

考虑一下,如果您正在嵌套的批处理文件中运行,请对此进行测试:

echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"
Run Code Online (Sandbox Code Playgroud)

将始终失败(不匹配),因为%newcmdcmdline%包含最外面的批处理文件的名称,而不是嵌套的批处理文件的名称。

因此,第一个解决方案对于调用的批处理文件以及所有嵌套的批处理文件将具有相同的行为。如果您不调用任何批处理文件,也很完美:

在要进行此测试的所有批处理文件(调用和嵌套)中,添加以下行,通常在批处理文件的顶部附近(如果需要,可以排除echo语句):

if not defined withincmd call :testshell
if %withincmd% EQU 0 echo This batch-file: %~dpf0 was executed directly (from Windows Explorer, ...).
if %withincmd% EQU 1 echo This batch-file: %~dpf0 was executed from within a Command Prompt
rem if %withincmd% EQU 0 pause
Run Code Online (Sandbox Code Playgroud)

然后,在每个批处理文件中的某处添加testshell子功能:

goto :EOF
:testshell
rem "Nested" batch-files won't see this because withincmd is already defined
if not defined newcmdcmdline set newcmdcmdline=%cmdcmdline:"=-%
set withincmd=1
echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% EQU 0 set withincmd=0
goto :EOF
Run Code Online (Sandbox Code Playgroud)

您只能在最外层批处理文件的顶部一次对“ testshell”进行条件调用。

在某些情况下,如果您是从“命令提示符”执行的,则与通过单击批处理文件(或批处理文件的快捷方式)运行时相比,可能只希望“最外层”批处理文件的行为有所不同。从“ Windows资源管理器”。因此,无论如何运行,从“最外层”批处理文件调用的批处理文件将始终表现相同。

为此,您有几种选择。

1)在调用另一个批处理文件之前保存“ withincmd”的值,并在被调用的批处理文件返回后恢复“ withincmd”的先前值。在大多数情况下,这有点涉及。

2)在每个批处理文件中为“ withincmd”使用“全局唯一”变量名称。

3)每次需要了解当前批处理文件的运行方式时,都要执行“查找”命令。

4)在进入批处理文件时增加一个变量,并在退出批处理文件时减小它,然后仅在count-variable = 1时测试批处理文件的运行方式

方法3是最简单的方法,但缺点是,如果从自身(如在递归中)或另一个批处理文件中调用最外面的批处理文件,则将无法正确设置测试变量(withincmd)。

使用方法3的方法如下:

在要进行此测试的所有批处理文件(调用和嵌套)中,添加以下行,通常在批处理文件的顶部附近(如果需要,可以排除echo语句):

call :testshell
if %withincmd% EQU 0 echo This batch-file: %~dpf0 was executed directly (from Windows Explorer, ...).
if %withincmd% EQU 1 echo This batch-file: %~dpf0 was executed from (or Nested) within a Command Prompt
rem if %withincmd% EQU 0 pause
Run Code Online (Sandbox Code Playgroud)

然后,在每个批处理文件中的某处添加testshell子功能:

goto :EOF
:testshell
if not defined newcmdcmdline set newcmdcmdline=%cmdcmdline:"=-%
set withincmd=1
echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% EQU 0 set withincmd=0
goto :EOF
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您必须在EACH批处理文件的顶部调用一次“ testshell”,然后在调用另一个批处理文件返回后再次调用(或者每次您需要了解当前的批处理文件已运行)。

使用方法4的方法如下:

在要进行此测试的所有批处理文件(调用和嵌套)中,添加以下行,通常在批处理文件的顶部附近(如果需要,可以排除echo语句):

if not defined nestinglevel set nestinglevel=0
set /A nestinglevel=nestinglevel+1
call :testshell
if %withincmd% EQU 0 echo This batch-file: %~dpf0 was executed directly (from Windows Explorer, ...).
if %withincmd% EQU 1 echo This batch-file: %~dpf0 was executed from (or Nested) within a Command Prompt
rem if %withincmd% EQU 0 pause
Run Code Online (Sandbox Code Playgroud)

然后,在每个批处理文件中的某处添加testshell子功能:

goto :EOF
:testshell
if not defined newcmdcmdline set newcmdcmdline=%cmdcmdline:"=-%
set withincmd=1
if %nestinglevel% GEQ 2 goto :EOF
echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% EQU 0 set withincmd=0
goto :EOF
Run Code Online (Sandbox Code Playgroud)

另外,请记住在退出一个批处理文件以返回到调用批处理文件时减小该变量:

set /A nestinglevel=nestinglevel-1
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您必须在EACH批处理文件的顶部调用一次“ testshell”,然后在调用另一个批处理文件返回后再次调用(或者每次您需要了解当前的批处理文件已运行)。

在所有情况下,请测试%withincmd%以确定当前批处理文件的运行方式,如下所示:

if %withincmd% EQU 0 pause
if %withincmd% EQU 1 goto :EOF
Run Code Online (Sandbox Code Playgroud)


小智 1

%cmdcmdline%如果通过鼠标双击启动,则包含当前批处理文件名(否则它仅包含CMD.exe路径)。

因此,在批处理文件末尾,如果%~nx0在以下位置找到批处理文件名,我会暂停%cmdcmdline%

echo %cmdcmdline%|findstr /c:"%~nx0" >nul
if %errorlevel% equ 0 echo.&pause
Run Code Online (Sandbox Code Playgroud)