Come impedire la chiusura del prompt dei comandi dopo l'esecuzione?


55

Il mio problema è che in Windows ci sono finestre della riga di comando che si chiudono immediatamente dopo l'esecuzione. Per risolvere questo, voglio che il comportamento predefinito sia che la finestra sia aperta. Normalmente, questo comportamento può essere evitato con tre metodi che mi vengono in mente:

  1. Inserire una pauseriga dopo i programmi batch per richiedere all'utente di premere un tasto prima di uscire
  2. Esecuzione di questi file batch o altri strumenti di manipolazione della riga di comando (anche l'avvio del servizio, il riavvio, ecc. Con net start xyo qualcosa di simile) all'interno di cmd.exe(Start - Esegui - cmd.exe)
  3. Eseguendo questi programmi in cmd /kquesto modo: cmd /k myprogram.bat

Ma ci sono altri casi in cui l'utente:

  1. Esegue il programma la prima volta e non sa che il programma specificato verrà eseguito nel Prompt dei comandi (Processore di comandi di Windows), ad esempio quando si esegue un collegamento dal menu Start (o da qualche altra parte), OPPURE
  2. Trova un po 'scomodo eseguire cmd.exe in ogni momento e non ha il tempo / l'opportunità di riscrivere il codice di questi comandi ovunque per mettere una pausa dopo di loro o evitare di uscire esplicitamente.

Ho letto un articolo sulla modifica del comportamento predefinito di cmd.exequando lo si apre esplicitamente, con la creazione di una voce AutoRun e la manipolazione del suo contenuto in queste posizioni:

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

(Gli elementi AutoRun sono _String values_...)

L'ho messo cmd /d /kcome valore per provarlo, ma questo non ha cambiato affatto il comportamento delle cose menzionate sopra ... Ha solo cambiato il comportamento della finestra della riga di comando all'apertura esplicita (Start-Run- cmd.exe).

Quindi, come funziona? Potete darmi qualche idea per risolvere questo problema?


10
La tua domanda con tutte le spiegazioni mi ha fatto esplodere la testa. Puoi dire qualcosa del tipo: Voglio eseguire un file batch con questo comando "esempio" e voglio che la finestra di comando rimanga aperta al termine. È quello che stai chiedendo? Inserisci un campione ravvicinato del codice.
KCotreau,

1
+1 concordato. Un po 'prolisso, per favore riconsidera la tua domanda e, se possibile, usa un esempio e componi una domanda più concisa.
slotishtype,

2
Questo è un comportamento normale e, sebbene la tua domanda sia certamente valida, dovresti chiederti perché è necessario mantenere aperto il prompt dei comandi dopo (la maggior parte dei programmi di utilità vengono creati tenendo presente questo avvertimento).
Sfondamento

1
Secondo me, questa non è una vera domanda. Come appena istruito l'utente a utilizzare invece un file batch. Se questo non è lo scopo della domanda, chiarisci la tua domanda rimuovendo qualsiasi informazione confusa e spiega qual è il tuo vero obiettivo. È difficile trovare la risposta giusta se non è chiaro ...
Tamara Wijsman,

1
@Randolf Richardson, è perché quegli strumenti non dovrebbero mai essere visti da un utente finale (dopotutto, ecco perché ora usiamo le GUI). Se sono necessarie tali informazioni, la maggior parte dei gruppi IT invierà file batch per raccogliere le informazioni di sistema appropriate e visualizzarle. Non vedo in alcun modo che se viene trovata una soluzione a questa domanda, causerà meno problemi, quindi risolverà - così tante cose vengono inviate stdoutsu base costante che non sono mai state pensate per essere visibili per una buona ragione.
Sfondamento

Risposte:


27

Ho una soluzione che può essere applicata solo su .cmde .batfile:

Apri regedite vai a ciascuno di:

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

Ora modifica il "Valore chiave predefinito" in cmd.exe /k "%1" %*. Ora, ogni finestra di script batch rimarrà aperta dopo la sua esecuzione.

Nota che è come usare cmd.exe /c cmd.exe /k program.bat, il che significa che un'altra istanza CMD verrà lanciata in quella genitore. Non sono riuscito a trovare come sovrascrivere il primo /cargomento.

Puoi anche farlo con [exefile], ma ora mostrerà una console vuota se l'eseguibile ha una GUI.


4
+1 per avere l'unica soluzione qui che risponde effettivamente alla domanda fornita. Sfortunatamente, penso che questa potrebbe essere una perdita di memoria in attesa di accadere. Cosa succede quando un servizio avvia un nuovo file batch senza specificare CMD.EXE nella riga CMD? Questo codice non verrà utilizzato in quel caso? Non creerà una nuova finestra su un desktop non interattivo e la lascerà aperta fino al riavvio?
krowe2,

@APerson La tua modifica ha violato il comando non includendo il *. Prestare maggiore attenzione durante la modifica!
not2qubit,

@ not2qubit Spiacenti, non ho notato che ho eliminato tre asterischi anziché due. Andrà bene.
APerson,

17

Citazione Microsoft :

Una console viene chiusa quando termina l'ultimo processo collegato o chiama FreeConsole.

In altre parole, la finestra della console Win32 verrà sempre chiusa quando si chiude l'ultimo programma in esecuzione al suo interno e non è possibile modificarlo.


(Per i programmi MS-DOS a 16 bit, Windows offre un'opzione "Chiudi all'uscita" nella finestra di dialogo delle proprietà, ma questa non è un'eccezione al comportamento sopra: è il processo NTVDM che tiene aperta la finestra. Inoltre, questa opzione è di nuovo per programma.)


13
+1 per capire come e perché le finestre della console si chiudono (al contrario della maggior parte di coloro che dicono semplicemente "OMG PERCHÉ NON PUOI SOGGIORNARE APERTO !!!!!!!!!!! 1111one"). Si comporta come progettato e dovrebbe rimanere in questo modo IMHO. Questo è il motivo principale per cui abbiamo flussi standard e file batch in primo luogo.
Breakthrough

27
@Breakthrough La domanda è How can I do Xno In your opinion, should I do X. Questa risposta è inutile, implica che X è impossibile, quando soluzioni parziali sono già state presentate altrove. (-1)
Superbo

8

Basta aprire un prompt dei comandi nella posizione del file batch e digitare manualmente il nome del file batch per eseguirlo all'interno di quella finestra.

1. Passa alla cartella in cui risiede il tuo eseguibile
2.Mai premuto il tasto destro del mouse e seleziona "Finestra di comando da qui"
3.tipe il nome dell'eseguibile e premi invio
4. Il processo dovrebbe essere eseguito, ma la finestra dovrebbe rimanere aperta


1
Non sapevo di Maiusc + tasto destro. Inoltre, puoi anche trascinare e rilasciare l'exe in una finestra cmd, che inserisce automaticamente il percorso per te.
Superbo

1
Questo di solito funziona per me, ma a quanto pare non è una cosa certa perché sono qui alla ricerca di una soluzione proprio perché non funziona nella mia situazione attuale.
RenniePet,

questa è la soluzione più semplice e deve essere contrassegnata come la risposta corretta
Vicky Kapadia

4

cmd.exe /kti darà problemi con alcuni lotti. Se il batch exit 1(senza /B) la tua console verrà chiusa. Un trucco è usare:

cmd.exe /k cmd /c ...

Per utilizzare questo per impostazione predefinita per tutti i file batch, impostare HKEY_CLASSES_ROOT\cmdfile\shell\open\command\(default)e HKEY_CLASSES_ROOT\batfile\shell\open\command\(default)su "%windir%\system32\cmd.exe" /k "%windir%\system32\cmd" /c "%1" %*.


1
Ho pensato che "%*"passa l'elenco completo dei parametri, quindi questo non passerebbe due volte il primo parametro, una volta tanto "%1"come il primo parametro di "%*"?
Kevin Fegan,

1
@KevinFegan Non ho verificato il motivo ma% 1 dovrebbe mantenere le virgolette, il che significa che in alcuni casi potrebbe essere doppie. C'è anche una differenza tra %1 %2 %3 ..e %*che non ricordo in questo momento, ma i %1 %2 %3lavori in alcuni casi %*falliscono.
Wernight,

3

Ho appena trovato una soluzione stupida dopo aver letto grawityla risposta.

Il mio caso d'uso consisteva nell'impostare un ambiente console al lavoro in cui venivano bloccate tutte le soluzioni più ragionevoli. Tutto ciò di cui ho bisogno è impostare PATH e configurare alcuni alias doskey ed essere scaricato nella shell.

La mia soluzione (appena testata su Win7) come aggiunta cmdcome ultima riga nel file batch. Questo esegue un prompt dei comandi nidificato che eredita l'ambiente del suo genitore. Quella shell figlio mantiene aperto il processo batch fino a quando non si esce, a quel punto il batch non ha processi figlio ed esce.


2

Piuttosto che usare PAUSE (preferisco CHOICE o TIMEOUT all'utilizzo di PAUSE quando necessario), puoi usare la soluzione qui: 886848 / come-fare-windows-batch-file-pausa-quando-doppio-clic .

In questo modo, se si fa clic su un file batch o su un collegamento (collegamento) da Esplora risorse, è possibile mettere in pausa il programma del file batch prima che esca, in modo da poter visualizzare l'output del programma e tutti i messaggi di errore.

Utilizzando CHOICE, è possibile programmare la possibilità per l'utente di selezionare una varietà di azioni da eseguire e l'utilizzo di TIMEOUT può far chiudere la finestra dopo un intervallo di tempo (incustodito). Se si esegue il file batch da una finestra del prompt dei comandi, queste pause possono essere fastidiose.

La soluzione collegata consente di decidere se si desidera saltare le pause se il file batch è stato eseguito da una finestra del prompt dei comandi.

Puoi leggere di più sul link fornito, ma la base è che utilizza la variabile di ambiente:

%cmdcmdline%

per determinare se il file batch è stato eseguito da una finestra di comando o meno.

Quindi, lo usi in questo modo:

Nel punto in cui uscirà il file batch, aggiungi del codice in questo modo:

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

Il modo migliore che ho trovato per aggirare questo è chiamare i tuoi file batch da un altro file batch usando start.

quindi se normalmente esegui un file chiamato go.bat, allora creeresti un secondo file batch chiamato qualcosa come go2.bat

il contenuto di go2.bat sarebbe semplicemente

start go.bat

la prima finestra si chiude immediatamente, ma quella che esegue go.bat rimane aperta


Questo funziona, ho appena messo il nome dell'eseguibile del prompt dei comandi in un file bat (1.bat) che viene chiamato usando il comando start da un secondo file bat "start 1.bat". La finestra di comando rimane aperta.
ejectamenta,

1

Funziona con la versione 5.00 dell'Editor del registro di Windows.

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

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

Salvare i cmds sopra in un file chiamato qualcosa di simile cmdbatfile-open.reged eseguirlo!


2
Benvenuto in Stack Exchange! Ho corretto la formattazione nella tua risposta per te. Vedi qui per l'aiuto sulla formattazione. Inoltre, quando pubblichi un codice, ricorda di spiegare cosa fa esattamente. Potresti anche voler leggere il tutorial su come rispondere .
Blacklight Shining

1

Supponiamo di avere due file batch che si desidera avviare nella propria istanza e tenerli aperti se il loro eseguibile esce. Chiamiamo quei due lotti A.bate B.bat.

Ora per semplicità potresti avere un file batch per avviarli entrambi, chiamiamolo launch_both.batcon i contenuti:

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

Potrebbe non funzionare come previsto se si chiama exitin uno dei due file batch. Questo dovrà essere testato.


0

Per gli utenti che utilizzano Windows 10, nota che nessuna delle risposte precedenti funziona attualmente per Windows 10.

Per Windows 10, se hai accesso allo script, devi aggiungere il seguente codice alla fine:

read

Quel codice attenderà un input prima della chiusura.


Ricorda che la domanda è stata posta prima di Windows 10 (5 anni fa), modifica la tua risposta con ulteriori informazioni
yass

0

In risposta al downgrade di PSIXO - "Questa risposta era già coperta dalla domanda. - Ro Yo Mi 20 gennaio 16 alle 5:06" - NO, NON lo era. Le risposte precedenti erano: "pausa", che NON ha funzionato. La risposta di PSIXO è stata: "& pause", che funziona. Si prega di analizzare più attentamente prima di eseguire il downgrade. L'ho eseguito da un prompt IDLE e ha funzionato:

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

D'altro canto:

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

NON ha funzionato (il prompt di cmd è stato capovolto e in effetti ha restituito un errore (1)). Grazie a PSIXO per la risposta di cui avevo bisogno. Henry.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.