Как сделать пакетный файл Windows приостановленным при двойном щелчке?

Я написал пакетный файл для автоматизации некоторых задач. Я могу запустить его из командной строки, и он запускает и отображает результаты. Если я дважды кликнул его из проводника, он запускается и заканчивается немедленно, поэтому я не вижу результатов.

Есть ли способ заставить окно пакетного файла оставаться открытым до тех пор, пока я его не отпущу, если я запустил его, дважды щелкнув значок?

Я не хочу передавать параметр /nopause или что-то, когда я вызываю командный файл из командной строки. Мне нужно решение, в котором я могу использовать командный файл без необходимости делать что-то особенное?

Спасибо.

ПРИМЕЧАНИЕ Я не хочу, чтобы он приостанавливался при запуске из командной строки!! Я могу вызвать этот пакетный файл из другого пакетного файла для выполнения нагрузки. В этом случае я не могу сидеть там, чтобы войти в игру.

В идеале было бы лучше, если бы я мог поместить некоторый код в пакетный файл, чтобы он мог работать там, откуда он был запущен, а затем приостановить или нет.

Ответ 1

Использование:

cmd /K myBatch.bat

в качестве ярлыка.

Ответ 2

Вот решение, которое должно хорошо работать и учитывать возможность того, что пакетный файл может вызвать другой пакетный файл ( "Вложенные" ).

Вы можете использовать Find, искать "/c", который не должен присутствовать, если пакетный файл запускается из "Командной строки":

echo %cmdcmdline% | find /i "/c"

Но вы можете сделать более "надежный" тест, используя "Найти" для поиска более длинной строки или имени файла партии.

Команда "Найти" не будет работать должным образом, если в строке поиска есть ( ") двойные кавычки внутри нее. Чтобы обойти это, вы можете использовать замену переменных среды для" настройки "строки, чтобы она хорошо играла с Find:

set newcmdcmdline=%cmdcmdline:"=-%

Это обычно возвращается:

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- -

Затем вы можете использовать "Найти" для тестирования, например:

    echo %newcmdcmdline% | find /i "cmd /c --"
or
    echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"

Далее вам нужно решить, хотите ли вы, чтобы командный файл "Вложенные" вел себя так, как если бы вы выполнили его так же, как вызывающий пакетный файл, или если вы хотите, чтобы вложенные командные файлы всегда вели себя так, как будто они были выполнены из "Командной подсказки".

Учтите, что если вы работаете в вложенном пакетном файле, то для этого выполните следующие проверки:

echo %newcmdcmdline% | find /i "cmd /c --%~dpf0%-"

всегда будет терпеть неудачу (нет соответствия), потому что% newcmdcmdline% содержит имя самого внешнего командного файла, а не вложенный пакетный файл.

Итак, первое решение будет вести себя одинаково для вызывающего пакетного файла и всех вложенных пакетных файлов. Также отлично, если вы не вызываете никаких пакетных файлов:

Во всех пакетных файлах (вызывающих и вложенных), которые вы хотите выполнить этот тест, добавьте эти строки, как правило, в верхней части пакетных файлов (вы можете исключить эхо-инструкции, если хотите):

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

Затем, где-нибудь внутри каждого пакетного файла, добавьте подфункцию testhell:

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

Вы вызываете только условный вызов "testhell" один раз, в верхней части самого большого пакетного файла.

В некоторых ситуациях вам может потребоваться, чтобы только "внешний" командный файл вел себя по-разному, если он выполняется из "Командной строки", если он запущен, нажав на пакетный файл (или пакетный файл) файл) из "Проводника Windows". Таким образом, пакетные файлы, вызываемые из "внешнего" командного файла, всегда будут вести себя одинаково независимо от того, как они выполняются.

Для этого у вас есть несколько вариантов.

1) Сохраните значение "внутриcmd" перед вызовом другого пакетного файла и восстановите предыдущее значение "внутриcmd" после возвращения вызванного пакетного файла. Это немного связано с большинством случаев.

2) Используйте имя переменной "global-unique" для "внутриcmd" в каждом пакетном файле.

3) Выполняйте команду "Найти" каждый раз, когда вам нужно знать, как был запущен текущий пакетный файл.

4) Увеличьте переменную при входе в пакетный файл и уменьшите ее на выходе пакетного файла, а затем проверьте только, как был запущен пакетный файл, если count-variable = 1

Метод 3 является самым простым, но имеет недостаток, что если внешний файл партии вызывается из себя (как в рекурсии) или в другой пакетный файл, тестовая переменная (внутриcmd) не будет правильно установлена.

Здесь, как это сделать, используя метод 3:

Во всех пакетных файлах (вызывающих и вложенных), которые вы хотите выполнить этот тест, добавьте эти строки, как правило, в верхней части пакетных файлов (вы можете исключить эхо-инструкции, если хотите):

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

Затем, где-нибудь внутри каждого пакетного файла, добавьте подфункцию testhell:

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

В этом случае вам нужно вызвать "testhell" один раз, вверху Batch файла EACH, затем снова после того, как вы вернетесь из вызова другого пакетного файла (или вызовите "testhell" каждый раз, когда вам нужно знать как был запущен текущий пакетный файл).

Здесь, как это сделать, используя метод 4:

Во всех пакетных файлах (вызывающих и вложенных), которые вы хотите выполнить этот тест, добавьте эти строки, как правило, в верхней части пакетных файлов (вы можете исключить эхо-инструкции, если хотите):

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

Затем, где-нибудь внутри каждого пакетного файла, добавьте подфункцию testhell:

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

Кроме того, не забудьте уменьшить значение переменной при выходе из одного пакетного файла, чтобы вернуться в вызывающий пакетный файл:

set /A nestinglevel=nestinglevel-1

В этом случае вам нужно вызвать "testhell" один раз, вверху Batch файла EACH, затем снова после того, как вы вернетесь из вызова другого пакетного файла (или вызовите "testhell" каждый раз, когда вам нужно знать как был запущен текущий пакетный файл).

Во всех случаях проверьте% внутриcmd%, чтобы определить, как был запущен текущий пакетный файл, например:

if %withincmd% EQU 0 pause
if %withincmd% EQU 1 goto :EOF

Ответ 3

в конце печати файла

pause

он будет ожидать ввода любых клавиш

Ответ 4

Моя проблема была похожа - я хотел сделать паузу в самом конце, если вызван из Проводника 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)

а затем в конце

if "%parent%"=="%~0" ( if "%console_mode%"=="0" pause )

Он обрабатывает вложенные пакетные вызовы, где требуется только приостановить действие в конце исходного пакетного файла, а не в вложенных пакетных файлах. Во вложенном пакетном файле %parent% уже установлен на исходный вызывающий, поэтому он не будет равен вложенному %~0. Если у вас есть bat1, который вызывает bat2, он открывает возможность двойного щелчка bat2 в Проводнике - в этом контексте bat2 будет останавливаться на конце, тогда как если bat1 вызывает bat2, тогда bat2 выиграл 't приостановить в конце (только bat1 остановится).

Разделитель операторов & помогает избежать визуального беспорядка для чего-то, что является вторичным по отношению к основной функции. Если вам не нравится внешний вид, просто поместите каждое утверждение в новую строку.

Этот подход ищет /C как один из параметров команды запуска (%cmdcmdline%). Предполагается, что ваши командные файлы не используют параметр /C. Если вы используете /C самостоятельно, вам нужно вместо этого проверить, появляется ли %COMSPEC% внутри %cmdcmdline% (используйте FINDSTR). Когда Explorer запускает bat файл, его %cmdcmdline% включает %COMSPEC% например C:\Windows\System32\cmd.exe /C double_clicked_batch_file_name. В командном окне %cmdcmdline% просто имеет cmd.exe в нем (нет пути). Я использую CALL mybat, а не cmd.exe /C mybat, но вам, возможно, придется работать с существующими пакетными файлами.

Ответ 5

вы можете просто добавить params к пакетному вызову и обработать условную паузу в своей партии. Поэтому при запуске из командной строки или dblclick пакет может приостанавливаться, когда вызываемые из других партий с параметром /nopause не приостанавливаются.

Ответ 6

используйте "паузу" в пакетном файле в конце, и он будет ждать ввода пользователем

НТН