52

Моя проблема в том, что в Windows есть окна командной строки, которые закрываются сразу после выполнения. Чтобы решить эту проблему, я хочу, чтобы по умолчанию было открыто окно. Обычно такого поведения можно избежать тремя способами, которые приходят мне в голову:

  1. Установка строки pause после пакетных программ, чтобы пользователь мог нажать клавишу перед выходом
  2. Запуск этих пакетных файлов или других инструментов управления командной строкой (даже запуск службы, перезапуск и т.д. С net start xy или чем-то подобным) в cmd.exe (Пуск - Выполнить - cmd.exe)
  3. Запуск этих программ с помощью cmd /k например: cmd /k myprogram.bat

Но есть и другие случаи, когда пользователь:

  1. Запускает программу в первый раз и не знает, что данная программа будет запускаться в командной строке (Windows Command Processor), например, при запуске ярлыка из меню «Пуск» (или из другого места), ИЛИ
  2. Несколько неудобно постоянно запускать cmd.exe, и у него нет времени / возможности везде переписывать код этих команд, чтобы ставить после них паузу или избегать явного выхода.

Я прочитал статью об изменении поведения cmd.exe умолчанию при его явном открытии с созданием записи автозапуска и манипулированием ее содержимым в следующих местах:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\AutoRun
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor\AutoRun

(Элементы _String values_ )

Я поставил cmd /d /k в качестве значения, чтобы попробовать, но это никак не изменило поведение вышеупомянутых вещей ... Он просто изменил поведение окна командной строки при его явном открытии (Start-Run-cmd.exe).

Итак, как это работает? Можете ли вы дать мне какие-либо идеи для решения этой проблемы?

11 ответов11

26

У меня есть решение, которое может применяться только к файлам .cmd и .bat :

Откройте regedit и перейдите к каждому из:

[HKEY_CLASSES_ROOT\batfile\shell\open\command]
[HKEY_CLASSES_ROOT\cmdfile\shell\open\command] 

Теперь измените "Значение ключа по умолчанию" на cmd.exe /k "%1" %* . Теперь каждое окно пакетного скрипта останется открытым после его выполнения.

Обратите внимание, что это похоже на использование cmd.exe /c cmd.exe /k program.bat , что означает, что другой экземпляр CMD будет запущен в родительский. Я не мог найти, как перезаписать первый аргумент /c .

Вы также можете сделать это с [exefile] , но теперь он покажет пустое поле консоли, если исполняемый файл имеет графический интерфейс.

14

Цитата Microsoft:

Консоль закрывается, когда последний присоединенный к ней процесс завершается или вызывает FreeConsole.

Другими словами, консольное окно Win32 всегда будет закрыто при выходе из последней программы, работающей внутри него, и вы не можете это изменить.


(Для 16-разрядных программ MS-DOS в диалоговом окне свойств Windows предлагается параметр "Закрыть при выходе", но это не исключение из описанного выше поведения: это процесс NTVDM, который удерживает окно открытым. Кроме того, эта опция снова для каждой программы.)

7

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

1.Перейдите в папку, где находится ваш исполняемый файл
2.Shift-правый клик и выберите "Окно команд из здесь"
3.Введите имя исполняемого файла и нажмите Enter
4.Процесс должен запускаться, но окно должно оставаться открытым

4

cmd.exe /k доставит вам неприятности с какой-то партией. Если пакетный exit 1 (без /B), ваша консоль будет закрыта. Хитрость заключается в использовании:

cmd.exe /k cmd /c ...

Чтобы использовать это по умолчанию для всех пакетных файлов, установите для HKEY_CLASSES_ROOT\cmdfile\shell\open\command\(default) и HKEY_CLASSES_ROOT\batfile\shell\open\command\(default) значение "%windir%\system32\cmd.exe" /k "%windir%\system32\cmd" /c "%1" %*.

3

Я просто grawity решение после прочтения ответа Гравити .

Моим примером использования была настройка консольной среды на работе, где все более разумные решения блокируются. Все, что мне нужно, это установить PATH, настроить псевдонимы doskey и сбросить их в оболочку.

Мое решение (только что протестировано на Win7), так как добавить cmd в качестве последней строки в командном файле. Это запускает вложенную командную строку, которая наследует среду своего родителя. Эта дочерняя оболочка удерживает пакетный процесс открытым до тех пор, пока вы не ВЫХОДИТЕ, и в этот момент пакет не имеет дочерних процессов и также завершает работу.

2

Вместо того, чтобы использовать PAUSE (я предпочитаю, чтобы CHOICE или TIMEOUT использовали PAUSE при необходимости), вы можете использовать решение здесь: 886848/how-to-make-windows-batch-file-pause-when-double-click.

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

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

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

Вы можете прочитать больше по предоставленной ссылке, но ее основа в том, что она использует переменную окружения:

%cmdcmdline%

определить, был ли командный файл запущен из командного окна или нет.

Итак, вы используете это так:

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

echo %cmdcmdline:"=-% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% NEQ 0 goto :EOF
pause
goto :EOF

rem if %errorlevel% EQU 0 batch-file: %~dpf0 was executed from Windows Explorer, ...
rem if %errorlevel% NEQ 0 batch-file: %~dpf0 was executed from within a Command Prompt
1

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

поэтому, если вы обычно запускаете файл с именем go.bat, то вы создадите второй пакетный файл с именем что-то вроде go2.bat

содержимое go2.bat будет просто

start go.bat

первое окно закрывается сразу, но то, что запускает ваш go.bat, остается открытым

1

Это работает для версии 5.00 редактора реестра Windows.

[HKEY_CLASSES_ROOT\batfile\shell\open\command]
@="cmd.exe /k \"%1\" %*"

[HKEY_CLASSES_ROOT\cmdfile\shell\open\command]
@="cmd.exe /k \"%1\" %*"

Сохраните вышеупомянутые cmds в файле с именем что-то вроде cmdbatfile-open.reg и выполните его!

1

Предположим, у вас есть два пакетных файла, которые вы хотите запустить в своем собственном экземпляре и держать открытыми, если их исполняемый файл завершается. Давайте назовем эти две партии A.bat и B.bat .

Теперь для простоты у вас может быть командный файл для запуска их обоих, давайте назовем этот launch_both.bat с содержимым:

start cmd /k "A.bat & cmd /c"
start cmd /k "B.bat & cmd /c"

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

0

Для пользователей, использующих Windows 10, обратите внимание, что ни один из ответов выше не работает в настоящее время для Windows 10.

Для Windows 10, если у вас есть доступ к сценарию, вам нужно добавить следующий код в конце:

read

Этот код будет ждать ввода перед закрытием.

0

В ответ на пониженную версию PSIXO - «Этот ответ уже был рассмотрен в вопросе. - Ro Yo Mi Jan 20 '16 в 5:06» - НЕТ, это не было. Предыдущие ответы были: "пауза", которая не сработала. PSIXO ответил: «& пауза», который работает. Пожалуйста, проанализируйте более внимательно, прежде чем понизить. Я запустил это из приглашения IDLE, и это сработало:

    >>> os.system('dir ^ & pause')
    0
    >>> 

С другой стороны:

    >>> os.system('dir ^ pause')
    1
    >>>

НЕ работало (приглашение cmd перевернулось и фактически вернуло ошибку (1)). Спасибо PSIXO за ответ, который мне был нужен. Генри.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .