Direkt zum Inhalt

Windows-Befehlszeile, Windows mit Registerkarten und JP-Software (Teil IV)

In meinem letzten Beitrag habe ich über einige der Strategien gesprochen, die ich während des Spiels ausprobiert habe, um Konsolenfenster in einem GUI-Fenster anzuzeigen Take Command 9 Design und Entwicklung.

Die ersten drei Ideen (die Windows-Barrierefreiheits-APIs, das Einfügen einer DLL in Konsolenanwendungen und die Zuweisung von Konsolen aus Take Command Sitzung) wurden alle verworfen, nachdem schwerwiegende Fehler aufgetreten waren. Idee Nr. 4 bestand darin, die Windows-Konsolen-APIs einzubinden, sodass ich jeden Aufruf zum Lesen oder Schreiben in ein Konsolenfenster abfangen konnte. (ReadConsole, ReadConsoleInput, WriteConsole, WriteConsoleOutput usw.) Theoretisch würde mir dies eine vollständige Abdeckung aller Konsolen-E/A bieten, sodass ich diese verarbeiten und die E/A optional ändern oder umleiten könnte, bevor ich sie weitergebe. In der Praxis stellte sich heraus, dass es alle Nachteile von Nr. 2 (Injizieren einer DLL) und noch einige weitere hatte:

  • Es erforderte die dynamische Änderung anderer Programme (siehe: Is Take Command mit einem Virus infiziert!?).
  • Es fügte hinzu Menge von zusätzlicher Komplexität.
  • Es schien keine Möglichkeit zu geben, die gelegentlichen mysteriösen API-Aufrufe abzufangen, die von irgendwo tief im Inneren von Windows zu stammen schienen und undokumentierte Konsolen-APIs auf niedrigerer Ebene aufriefen.
  • Ich bin auf eine weitere Reihe fehlerhafter und/oder falsch dokumentierter APIs gestoßen. (Einige davon hatte ich schon in den NT 3.x-Tagen gefunden – offenbar hat Microsoft in den letzten 15 Jahren nicht die höchste Priorität auf die Verbesserung des Konsolenfensters gelegt.)
  • Aufgrund der unzureichenden Dokumentation der Konsolen-APIs durch Microsoft wurden diese von vielen Programmen falsch aufgerufen. Ignoriere ich die schlechten Anrufe? Versuchen Sie, sie zu korrigieren und weiterzugeben? Oder verarbeiten Sie sie einfach wie gewünscht, leiten Sie sie weiter und hoffen Sie, dass sie nicht beschädigt werden Take Command zu schlecht angezeigt?

Als ich kurz davor stand, die ganze Idee von Konsolenfenstern mit Registerkarten zu verwerfen, dachte ich darüber nach, Idee Nr. 3 umzukehren. Anstatt Take Command Erstellen Sie die Konsole und starten Sie dann die Befehlszeilenanwendung in diesem Konsolenfenster. Was wäre, wenn ich die Befehlszeilenanwendung starten würde (die dann ein eigenes verstecktes Konsolenfenster erstellen würde) und dann eine Verbindung herstellen würde? Take Command zu diesem Konsolenfenster? Diese Idee hatte einige Vorteile:

  • Darüber würde sich kein Antivirenprogramm beschweren.
  • Take Command könnte das Konsolenfenster mit der Befehlszeilenanwendung teilen (z. B. TCC) und konnte direkt aus diesem Fenster lesen und in dieses schreiben, ohne dass eine Interprozesskommunikation zwischen ihnen erforderlich war Take Command und die Befehlszeilenanwendung.
  • Take Command konnte problemlos zwischen Tab-Fenstern wechseln, indem man die Verbindung zur vorherigen Konsole trennte und eine Verbindung zur neuen herstellte.

Natürlich würde es nicht so einfach sein. Es gab (selbst für Windows) ungewöhnlich viele Hindernisse:

  • Eine weitere scheinbar endlose Reihe fehlerhafter/falsch dokumentierter Windows-APIs. Beispielsweise verhielten sich einige APIs unerwartet oder schlugen ganz fehl, wenn das Konsolenfenster ausgeblendet war.
  • Es stellte sich heraus, dass es selbst für etwas so scheinbar Einfaches alles andere als trivial war Take Command um schnell und zuverlässig das Konsolenfenster-Handle der gerade gestarteten Anwendung abzurufen.
  • Der bloße Zugriff auf das Konsolenfenster bedeutete nicht, dass ich das aktualisieren konnte Take Command Fenster schnell.
  • Ich musste alle Konsolenfenster kontinuierlich überwachen (auch diejenigen, die in einem Tab-Fenster nicht sichtbar waren), damit ich feststellen konnte, ob die App beendet wurde, ihre Fenster- und/oder Puffergröße geändert hatte (nicht ungewöhnlich) und die Konsole (wieder) ausgeblendet hatte Fenster, wenn es irgendwie sichtbar geworden ist (wiederum nicht ungewöhnlich), aktualisieren Sie die Tab-Titel usw.
  • Erfassen Sie die Instanzen, in denen die Konsolenanwendung eine andere Anwendung gestartet und dann beendet hat (wobei die untergeordnete Anwendung weiterhin ausgeführt wird, jedoch mit einer anderen Prozess-ID).
  • Die Tastatureingabe musste bearbeitet werden Take Command, entsprechend gefiltert und dann an die Konsolenfenster übergeben.
  • Die Z-Reihenfolge des Fensters musste kontinuierlich angepasst werden, damit der Fokus an der richtigen Stelle lag.
  • Umgang mit der lästigen Tendenz von DOS-Apps, die Größe des Konsolenfensterpuffers auf 80×25 zu ändern. (Je weniger über die restlichen Probleme beim Ausführen von DOS-Apps gesagt wird, desto besser.)
  • Und so viele mehr, dass ich das Gefühl habe, in einen gefährlich depressiven Zustand zu verfallen, während ich den langen Albtraum noch einmal durchlebe …

Wenn ich alle Probleme gekannt hätte, auf die ich später stoßen würde, hätte ich weiter nach Idee Nr. 6 gesucht oder vielleicht einen Job als stellvertretender Geschäftsführer beim örtlichen McDonald’s angenommen. Aber ich wusste es nicht und so überwand ich die Probleme nach und nach, eins nach dem anderen, bis ich mich unterwarf. Gelegentlich durch unglaublich clevere Programmierung, meistens aber durch intensive heuristische Analyse (d. h. Versuch und Irrtum). Es stellt sich heraus, dass es einen guten Grund gibt, warum es nur eine kleine Handvoll anderer Anwendungen gibt, die versuchen, Fenster mit Registerkarten für Konsolenanwendungen zu implementieren (und die meisten davon funktionieren langsam und schlecht).

Dieser Ansatz wurde übernommen für Take Command Version 9 wird immer noch für Version 13 verwendet (optimiert und aktualisiert), und ich erwarte keine größeren architektonischen Änderungen in der nächsten Version.

Wir sind also auf dem neuesten Stand und ich kann wieder über neue Funktionen (und neue Probleme) sprechen.