Windows-Konsolenfenster mit Strg+D schließen - Lösung

Dalai

Grand Admiral Special
Mitglied seit
14.06.2004
Beiträge
7.420
Renomée
262
Standort
Meiningen, Thüringen
Hallo Leute,

ich hatte heute Nacht eine Eingebung ;D für das folgende Problem:

  • Wie schließt man ein Konsolenfenster unter Windows mit Strg+D, wie man es von jeder vernünftigen Linux-Shell gewohnt ist?
Im Folgenden die von mir erdachte Lösung. Das Ganze ist ein AutoIt-Skript, was man sich kompilieren kann (muss man aber nicht, direktes Ausführen geht natürlich auch) und dann die ganze Zeit im Hintergrund läuft.

Funktionsweise des Skripts:
  1. Wenn Strg+D gedrückt wird, holt sich das Skript die PID des im Vordergrund befindlichen Programms und eine Liste aller Prozesse namens "cmd.exe"
  2. Die Prozessliste wird dann mit der einzelnen PID verglichen
  3. Stimmt eine PID mit der einzelnen PID überein, handelt es sich um eine "cmd.exe", die im Vordergrund ist, und es wird "exit" an dieses Fenster gesendet.

Changelog:
Code:
Vollkommen vergessen, das Strg+D an die Applikation zu senden, wenn es keine CMD ist *buck*
- Änderungen diesbzgl. eingepflegt

Kommandozeilen-Parameter "hide" hinzugefügt:
- ermöglicht das Verstecken des Trayicons, so dass das Programm komplett versteckt laufen kann.

Code:
;
; AutoIt Version: 3.10
; Language:       All
; Platform:       Win2000/XP/2003
; Author:         Dalai
;
; Last Update: 09.06.2008
;
; Script Function:
;    Close CMD window when Ctrl+D is pressed
;
; ----------------------------------------------------------------------------
; Set up our defaults
; ----------------------------------------------------------------------------

;Shows the current script line in the tray icon tip to help debugging
AutoItSetOption("TrayIconDebug", 1)

;#NoTrayIcon

if $CmdLine[0] > 0 then
   if ($CmdLine[1] == "hide") then
       Opt("TrayIconHide", 1)
   EndIf
EndIf

; ----------------------------------------------------------------------------
; Script Start
; ----------------------------------------------------------------------------

global $proz_list
global $active_pid
global $sent=0

HotKeySet("^d", "DO_IT")

; -- Programm unendlich ausführen
while 1
    Sleep(10000)
WEnd


; ----------------------------------------------------------------------------

Func DO_IT()
     ; -- Prüfvariable zurücksetzen
     $sent=0

     ; -- Prozessliste der aktiven CMDs holen
     $proz_list = ProcessList("cmd.exe")
     
     ; -- Die PID des im Vordergrund befindlichen Programms holen
     $active_pid = WinGetProcess("")
     
     ; -- wenn die Prozessliste der aktiven CMDs etwas enthält bzw. ein Array ist ...
     if IsArray($proz_list) then
        ; -- ... das Feld durchlaufen ...
        for $i=1 to $proz_list[0][0]
            ; -- ... und jede PID der aktiven CMDs mit der PID des im VG befindlichen Programms vergleichen.
            ; -- Wenn Übereinstimmung gefunden, dann ...
            if ($active_pid == $proz_list[$i][1]) then
               ; -- ... "exit" an dieses Fenster senden
               Send("exit" & @CRLF)
               ; -- und Prüfvariable setzen
               $sent=1
            EndIf
        Next
        ; -- Wenn es keine CMD ist, ...
        if ($sent==0) then
            ; -- ... Hotkey deregistrieren 
            ; -- (sonst landen wir in einer unendlichen rekursiven Schleife) ...
            HotKeySet("^d")
            ; -- ... Strg+D an die Applikation senden ...
            Send("^d")
            ; -- ... und Hotkey wieder registrieren
            HotKeySet("^d", "DO_IT")
        EndIf
     EndIf
EndFunc

Wer das Trayicon nicht sehen will, muss die Zeile mit dem AutoItSetOption("TrayIconDebug", 1) auskommentieren und die Zeile mit #NoTrayIcon "freischalten".

Ich bitte um Kritik, Verbesserungsvorschläge und ähnliches.

Eine kompilierte Version kommt noch; Link werde ich dann ins Post einfügen.
Hier nun die kompilierte Version: Klick mich.
Das ZIP enthält den obigen Quelltext und eine EXE. Die EXE ist so kompiliert (mit AutoIt 3.1.122), dass ein Dekompilieren möglich ist. Somit kann jeder nachprüfen, dass das Ding tatsächlich nur das macht, was oben auch steht, und kein Virus o.ä. enthalten ist.

[EDIT] Neuer Downloadlink [/EDIT]

MfG Dalai
 
Zuletzt bearbeitet:
Ähh gut und wozu genau braucht man das? Ich kann doch einfach aufs X klicken bzw. für die klickfaulen kann man ja auch einfach exit eingeben, wenn man die Hände eh schon auf der Tastatur hat. Da würden mir bessere Dinge einfallen, die ich da drauflegen kann. Die Kommandozeile braucht man eh nur, wenn man gerade etwas programmieren will, dass ein Programm mit Parametern aufruft bzw. Parameter entgegennimmt. Ich würde lieber etwas machen, dann er mein Strg+V frisst.
 
andr_gin schrieb:
Ich kann doch einfach aufs X klicken bzw. für die klickfaulen kann man ja auch einfach exit eingeben, wenn man die Hände eh schon auf der Tastatur hat.
Das Eingeben von "exit" ist eben viel zu viel. Wer die Linux-Shells kennt, der weiß das zu schätzen, nur 2 Tasten drücken zu müssen statt 5. Und die Hand an die Maus zu bewegen ist ebenfalls viel zu viel, wenn man eh grad auf der Konsole was eingegeben und damit die Hände an der Tastatur hat.

andr_gin schrieb:
Die Kommandozeile braucht man eh nur, wenn man gerade etwas programmieren will, dass ein Programm mit Parametern aufruft bzw. Parameter entgegennimmt
Richtig. Und genau das kommt bei mir relativ häufig vor. Deswegen hab ich meinen Einfall auch umgesetzt.

andr_gin schrieb:
Ich würde lieber etwas machen, dann er mein Strg+V frisst.
Kann ich dir programmieren, analog zu dem obigen Prog.

MfG Dalai
.
EDIT :
.

Hier meine Lösung zum Benutzen von Strg+V in der CMD. Vorsicht aber bei Grafiken in der Zwischenablage! Ich weiß nicht, was damit passiert. Das Skript sendet den Inhalt in jedem Fall an die CMD, egal, was drin ist.

Code:
;
; AutoIt Version: 3.10
; Language:       All
; Platform:       Win2000/XP/2003
; Author:         Dalai
;
; Last Update: 10.06.2008
;
; Script Function:
;    Paste text from clipboard to CMD
;
; ----------------------------------------------------------------------------
; Set up our defaults
; ----------------------------------------------------------------------------

;Shows the current script line in the tray icon tip to help debugging
AutoItSetOption("TrayIconDebug", 1)

;#NoTrayIcon

if $CmdLine[0] > 0 then
   if ($CmdLine[1] == "hide") then
       Opt("TrayIconHide", 1)
   EndIf
EndIf

; ----------------------------------------------------------------------------
; Script Start
; ----------------------------------------------------------------------------

global $proz_list
global $active_pid
global $sent=0

HotKeySet("^v", "DO_IT")

; -- Programm unendlich ausführen
while 1
    Sleep(10000)
WEnd


; ----------------------------------------------------------------------------

Func DO_IT()
     ; -- Prüfvariable zurücksetzen
     $sent=0

     ; -- Prozessliste der aktiven CMDs holen
     $proz_list = ProcessList("cmd.exe")
     
     ; -- Die PID des im Vordergrund befindlichen Programms holen
     $active_pid = WinGetProcess("")
     
     ; -- wenn die Prozessliste der aktiven CMDs etwas enthält bzw. ein Array ist ...
     if IsArray($proz_list) then
        ; -- ... das Feld durchlaufen ...
        for $i=1 to $proz_list[0][0]
            ; -- ... und jede PID der aktiven CMDs mit der PID des im VG befindlichen Programms vergleichen.
            ; -- Wenn Übereinstimmung gefunden, dann ...
            if ($active_pid == $proz_list[$i][1]) then
               ; -- ... Inhalt der Zwischenablage an dieses Fenster senden
               Send(ClipGet())
               ; -- und Prüfvariable setzen
               $sent=1
            EndIf
        Next
        ; -- Wenn es keine CMD ist, ...
        if ($sent==0) then
            ; -- ... Hotkey deregistrieren 
            ; -- (sonst landen wir in einer unendlichen rekursiven Schleife) ...
            HotKeySet("^v")
            ; -- ... Strg+V an die Applikation senden ...
            Send("^v")
            ; -- ... und Hotkey wieder registrieren
            HotKeySet("^v", "DO_IT")
        EndIf
     EndIf
EndFunc

Download des ZIPs: Klick mich. Enthält wieder EXE und den obigen Quelltext.

[EDIT] Neuer Downloadlink [/EDIT]

MfG Dalai
 
Zuletzt bearbeitet:
Das Eingeben von "exit" ist eben viel zu viel. Wer die Linux-Shells kennt, der weiß das zu schätzen, nur 2 Tasten drücken zu müssen statt 5. Und die Hand an die Maus zu bewegen ist ebenfalls viel zu viel, wenn man eh grad auf der Konsole was eingegeben und damit die Hände an der Tastatur hat.
Da muss mann aber für die Strg Taste aber die Fingerstellung ändern und dafür bin ich viel zu faul. Das mit der Maus ist immer auch Ansichtssache. Mein Vorgänger in der Arbeit hat nur mit der Maus geklickt und immer wenn er die Windows Taste gebraucht hat (so ca. 1 mal pro Minute), hat er mich gerufen, damit ich sie ihm im VNC drücke. Ich kann mich noch gut erinnern: Taste bitte - willst du mich verarschen - nein mir macht das nur zu viel Arbeit - grr na gut *drück*... Taste bitte - was denn schon wieder? - ja - geht das denn nicht mit klicken? - nein - na gut einmal noch *drück*.... Taste - Grrr nicht schon wieder *drück*... Taste - du willst heute unbedingt ein paar Zähne verlieren oder?

Hier meine Lösung zum Benutzen von Strg+V in der CMD. Vorsicht aber bei Grafiken in der Zwischenablage! Ich weiß nicht, was damit passiert. Das Skript sendet den Inhalt in jedem Fall an die CMD, egal, was drin ist.

Na das ist ja schon einmal etwas sehr sinnvolles. Da spare ich mir immer eine Menge Arbeit;D
 
Hier meine Lösung zum Benutzen von Strg+V in der CMD. Vorsicht aber bei Grafiken in der Zwischenablage! Ich weiß nicht, was damit passiert. Das Skript sendet den Inhalt in jedem Fall an die CMD, egal, was drin ist.

das ist sehr nice, vielen dank!
 
Wozu in die Ferne schweifen:

Wie sieht es mit ALT-F4 aus?
Das schließt doch auch die Konsole und wäre 2 Tasten ;)

lg
__tom
 
tomturbo schrieb:
Wie sieht es mit ALT-F4 aus?
Nein, eben das geht weder bei Win2k noch bei WinXP. Von Vista weiß ich nix.

MfG Dalai
 
Nein, eben das geht weder bei Win2k noch bei WinXP. Von Vista weiß ich nix.

MfG Dalai
Oh tatsächlich.
Wie bescheuert doch die MS Welt ist. Das darf nicht wahr sein *admin*

Hm, ich werde mich mal umhören ...

lg
__tom
 
tomturbo schrieb:
Hm, ich werde mich mal umhören ...
Im ersten Post steht doch eine Lösung ;D.

Im Ernst: um F4 auch zum Schließen der CMD nutzen zu können, müsste man bloß jedes Vorkommen von
Code:
"^d"
durch ein
Code:
"!{F4}"
ersetzen und ggf. noch das
Code:
Send("exit" & @CRLF)
durch ein
Code:
WinClose("")
damit das Fenster sofort geschlossen wird, unabhängig davon, ob in der CMD grade ein Befehl läuft.
Schon kann man F4 ebenfalls zum Schließen der CMD nutzen.

Ob das sinnvoll ist oder ob das wirklich funktioniert, will ich grade aus Faulheit und Zeitmangel nicht ausprobieren ;).

MfG Dalai
 
Ja klar, aber ein extra Programm kann doch wohl nicht die Lösung sein :]
Ist zwar eine nette Übung aber dennoch ein Fehler vom BS Hersteller, imo

lg
__tom
 
Ja klar, aber ein extra Programm kann doch wohl nicht die Lösung sein :]
Ist zwar eine nette Übung aber dennoch ein Fehler vom BS Hersteller, imo
Natürlich liegt der Fehler beim Hersteller des OS. Aber wenn man immer auf eine Lösung vom Programmierer wartet, kann man nie effektiv arbeiten, vor allem bei den Reaktionszeiten von MS ;D. Dazu kommt noch, dass das für MS wohl ein zu unwichtiger Fehler ist.

MfG Dalai
 
Obige Lösung zum Schließen der CMD hat einen lästigen Nebeneffekt: ist das vorletzte aktive Fenster eines vom Total Commander und das aktive eine CMD, die man mit Strg+D schließt, so reagiert TC auf diese Kombination, indem dessen Kommandozeile erscheint mit dem zuletzt benutzten Befehl drin. Es kann auch sein, dass noch andere Programme betroffen sind, aber das ist nunmal das bei mir am häufigsten benutzte ;D.

Deswegen habe ich heute nochmal drüber nachgedacht und folgende Änderung vorgenommen (fett gekennzeichnet):
Code:
;
; AutoIt Version: 3.10
; Language:       All
; Platform:       Win2000/XP/2003
; Author:         Dalai
;
; Last Update: 27.06.2009
;
; Script Function:
;    Close CMD window when Ctrl+D is pressed
;
; ----------------------------------------------------------------------------
; Set up our defaults
; ----------------------------------------------------------------------------

;Shows the current script line in the tray icon tip to help debugging
AutoItSetOption("TrayIconDebug", 1)

;#NoTrayIcon

if $CmdLine[0] > 0 then
   if ($CmdLine[1] == "hide") then
       Opt("TrayIconHide", 1)
   EndIf
EndIf

; ----------------------------------------------------------------------------
; Script Start
; ----------------------------------------------------------------------------

global $proz_list
global $active_pid
global $sent=0

HotKeySet("^d", "DO_IT")

; -- Programm unendlich ausführen
while 1
    Sleep(10000)
WEnd


; ----------------------------------------------------------------------------

Func DO_IT()
     ; -- Prüfvariable zurücksetzen
     $sent=0

     ; -- Prozessliste der aktiven CMDs holen
     $proz_list = ProcessList("cmd.exe")
     
     ; -- Die PID des im Vordergrund befindlichen Programms holen
     $active_pid = WinGetProcess("")
     
     ; -- wenn die Prozessliste der aktiven CMDs etwas enthält bzw. ein Array ist ...
     if IsArray($proz_list) then
        ; -- ... das Feld durchlaufen ...
        for $i=1 to $proz_list[0][0]
            ; -- ... und jede PID der aktiven CMDs mit der PID des im VG befindlichen Programms vergleichen.
            ; -- Wenn Übereinstimmung gefunden, dann ...
            if ($active_pid == $proz_list[$i][1]) then
               ; -- ... "exit" an dieses Fenster senden
               [B]Send("exit" & "{ENTER}")[/B]
               ; -- und Prüfvariable setzen
               $sent=1
            EndIf
        Next
        ; -- Wenn es keine CMD ist, ...
        if ($sent==0) then
            ; -- ... Hotkey deregistrieren 
            ; -- (sonst landen wir in einer unendlichen rekursiven Schleife) ...
            HotKeySet("^d")
            ; -- ... Strg+D an die Applikation senden ...
            Send("^d")
            ; -- ... und Hotkey wieder registrieren
            HotKeySet("^d", "DO_IT")
        EndIf
     EndIf
EndFunc
Jeder Programmierer weiß, dass CRLF insgesamt 2 Zeichen sind und so hat wohl schon das CR eine Wirkung (Bestätigung des "exit") und das LF landet dann beim vorletzten aktiven Fenster. Mit dem ENTER passiert das nicht mehr.

MfG Dalai
 
Zurück
Oben Unten