Як запобігти закриттю командного рядка після виконання?


54

Моя проблема полягає в тому, що в Windows є вікна командного рядка, які закриваються одразу після виконання. Щоб вирішити це, я хочу, щоб поведінка за замовчуванням полягала в тому, що вікно залишається відкритим. Зазвичай такої поведінки можна уникнути трьома методами, які мені спадають на думку:

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

Але є й інші випадки, коли користувач:

  1. Запускає програму вперше і не знає, що дана програма буде запускатися в командному рядку (Windows Command Processor), наприклад при запуску ярлика в меню "Пуск" (або з іншого місця), АБО
  2. Зробити це трохи незручно запускати cmd.exe весь час і не має часу / можливості переписувати код цих команд скрізь, щоб поставити паузу після них або уникати явного виходу.

Я читав статтю про зміну поведінки за замовчуванням, cmd.exeколи явно відкриваєте її, створюючи запис AutoRun та маніпулюючи її вмістом у таких місцях:

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

То як це працює? Чи можете ви дати мені якісь ідеї для вирішення цієї проблеми?


10
Ваше запитання з усіма поясненнями змусило мою голову вибухнути. Чи можете ви сказати щось на кшталт: я хочу запустити пакетний файл з цією командою "example", і я хочу, щоб командне поле залишалося відкритим після завершення. Це ви просите? Будь ласка, введіть близький зразок коду.
KCotreau

1
+1 Погоджено. Трохи до детального розгляду, будь ласка, перегляньте своє запитання та, якщо можливо, скористайтеся прикладом та складіть більш лаконічне запитання.
slotishtype

2
Це нормальна поведінка, і хоча ваше запитання, безумовно, справедливе, вам слід задати питання, чому після цього потрібно тримати відкритий командний рядок (більшість утиліт створюються з цим застереженням).
Прорив

1
На мою думку, це не справжнє питання. Оскільки ви просто вказуєте користувачеві використовувати замість нього пакетний файл. Якщо це не ціле питання, будь ласка, уточніть своє запитання, видаливши будь-яку заплутану інформацію та поясніть, яка ваша реальна мета. Важко придумати правильну відповідь, якщо вона незрозуміла ...
Тамара Війсман

1
@Randolf Richardson, це тому, що ці інструменти не повинні бачитись кінцевим користувачем ніколи (зрештою, саме тому ми зараз використовуємо графічні інтерфейси). Якщо вам потрібна така інформація, більшість ІТ-груп надсилають пакетні файли, щоб зібрати їм відповідну системну інформацію та відобразити її. Я не бачу можливого способу, що якщо рішення цього питання буде знайдено, це спричинить менше проблем, то воно вирішить - так багато речей надсилаються stdoutна постійній основі, які ніколи не мали бути видимими з уважної причини.
Прорив

Відповіді:


27

У мене є рішення , яке може застосовуватися тільки .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], але тепер він покаже порожнє поле консолі, якщо у виконуваному файлі є графічний інтерфейс.


4
+1 за те, що тут є єдине рішення, яке фактично відповідає на задане питання. На жаль, я думаю, що це може бути витік пам'яті, який чекає цього. Що відбувається, коли служба запускає новий пакетний файл, не вказуючи CMD.EXE у рядку CMD? Чи не буде використовувати цей код у такому випадку? Хіба це не створить нове вікно на інтерактивному робочому столі та не відкриє його до перезавантаження?
krowe2

@APerson Ваша редакція порушила команду, не включивши *. Будьте уважнішими під час редагування!
not2qubit

@ not2qubit Вибачте, не помітив, що я видалив три зірочки замість двох. Зроблю.
Аперсон

17

Цитата Microsoft :

Консоль закривається, коли завершується останній доданий до неї процес або викликає FreeConsole.

Іншими словами, вікно консолі Win32 завжди буде закрито, коли завершується остання програма, що працює всередині неї, і ви не можете це змінити.


(Для 16-бітних програм MS-DOS Windows пропонує опцію "Закрити при виході" у діалоговому вікні властивостей, але це не є винятком з поведінки, наведеної вище: це NTVDM, який тримає вікно відкритим. Також ця опція є знову за програмою.)


13
+1 для розуміння того, як і чому вікна консолі закриваються (на відміну від більшості людей, які просто говорять "OMG ЧОМУ НЕ МОЖЕ ВІДКРИТИ !!!!!!!!!!! 1111one"). Він поводиться так, як задумано, і таким чином повинен залишатися IMHO. Це головна причина, чому у нас в першу чергу стандартні потоки та файли пакетної передачі.
Прорив

27
@Breakthrough Питання в тому How can I do X, ні In your opinion, should I do X. Ця відповідь не допомагає, це означає, що X неможливо, коли часткові рішення вже представлені в інших місцях. (-1)
Супербест

7

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

1.Зайдіть у папку, де розміщується ваш виконуваний файл.
2. Клацніть правою кнопкою миші та виберіть "Вікно команд звідси"
3.введіть назву виконуваного файлу та натисніть клавішу Enter.
Процес повинен запуститися, але вікно має залишатися відкритим


1
Я не знав про Shift + Клацніть правою кнопкою миші. Крім того, ви можете перетягнути exe у вікно cmd, яке автоматично ставить вам шлях.
Супербест

1
Зазвичай це для мене працює, але це, мабуть, не є впевненою справою, тому що я тут шукаю рішення саме тому, що це не працює в моїй нинішній ситуації.
RenniePet

це найпростіший варіант вирішення, і його слід позначити як правильну відповідь
Вікі Кападія

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" %*.


1
Я думав, що це "%*"передає повний список параметрів, тож чи не буде він передати перший параметр двічі, раз "%1"і знову як перший параметр "%*"?
Кевін Феган

1
@KevinFegan Я ще не перевіряв причину, але% 1 повинен зберігати лапки, а це означає, що в деяких випадках це може бути подвійне цитування. Існує також різниця між %1 %2 %3 ..і %*яку я не пам'ятаю зараз , крім %1 %2 %3робіт , в деяких випадках , коли %*не вдається.
Wernight

3

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

Моїм випадком використання було налаштування консольного середовища на роботі, де блокуються всі більш розумні рішення. Все, що мені потрібно, це встановити PATH і налаштувати деякі doskey псевдоніми і перекинутись на оболонку.

Моє рішення (щойно перевірене на Win7) як додати cmdяк останній рядок у пакетному файлі. Це запускає вкладений командний рядок, який успадковує середовище свого батьківського. Ця дочірня оболонка тримає пакетний процес відкритим до тих пір, поки ви не вийдете, і в цей момент партія не має дочірніх процесів, а також не виходить.


2

Замість того, щоб використовувати PAUSE (я віддаю перевагу CHOICE або TIMEOUT перед тим, як використовувати PAUSE при необхідності), ви можете використати рішення тут: 886848 / як робити вікна-batch-файл-пауза-коли-двічі клацнувши .

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

Використовуючи 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

Найкращий спосіб, який я знайшов, щоб обійти це, - викликати свої пакетні файли з іншого пакетного файлу, використовуючи запуск.

тож якщо ви зазвичай запускаєте файл під назвою go.bat, то ви створили б другий пакетний файл з назвою щось на зразок go2.bat

вміст go2.bat був би просто

start go.bat

перше вікно закривається негайно, але те, що працює у вашому go.bat, залишається відкритим


Це працює, я просто помістив ім'я виконуваного командного рядка в один файл bat (1.bat), який викликається за допомогою команди start з другого файлу bat "start 1.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та виконайте це!


2
Ласкаво просимо на обмін стеками! Я зафіксував форматування у вашій відповіді. Дивіться тут інформацію про форматування. Крім того, коли ви розміщуєте код, будь ласка, не забудьте пояснити, що саме це робить. Ви також можете прочитати інструкцію щодо відповіді .
Blacklight Shining

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

Цей код буде чекати введення до закриття.


Пам'ятайте, що питання було задано перед Windows 10 (5 років тому), відредагуйте свою відповідь додатковою інформацією
yass

0

У відповідь на занижений PSIXO - "Ця відповідь вже висвітлювалась у запитанні. - Ro Yo Mi 20 січня 16 о 16:06" - НІ, НЕ. Попередні відповіді були: "пауза", яка НЕ ​​спрацювала. Відповідь PSIXO була: "& pause", яка НЕ ​​працює. Будь ласка, проаналізуйте ретельніше перед пониженням. Я запустив це з підказки IDLE, і воно спрацювало:

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

З іншого боку:

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

НЕ працював (підказка cmd перекинулася, і насправді повернула помилку (1)). Дякую PSIXO за відповідь, який мені знадобився. Генрі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.