Ausgabe an ein Befehlsfenster ausgeben, wenn die Golang-Anwendung mit -ldflags -H = windowsgui kompiliert wird

8

Ich habe eine Anwendung, die normalerweise im Hintergrund läuft, also kompiliere ich sie mit

%Vor%

Um die Version in der Befehlszeile zu überprüfen, wollte ich ein Flag -V an die Befehlszeile übergeben, um die Zeichenfolge, die die zu druckende Version enthält, an die Eingabeaufforderung zu erhalten und das Programm zu beenden. Ich habe das Flag-Paket und den Code hinzugefügt. Wenn ich es mit

teste %Vor%

... druckt die Version gut. Wenn ich die EXE kompiliere, wird sie einfach beendet und druckt nichts. Ich vermute, es ist das Kompilierungs-Flag, das bewirkt, dass es nicht auf die Konsole zugreift und meinen Text in den Bit-Bucket sendet.

Ich habe versucht, Variationen in stderr und stdout zu drucken, indem ich println und fprintf und os.stderr.write verwende, aber nichts erscheint von der kompilierten Anwendung. Wie sollte ich versuchen, eine Zeichenfolge an die Eingabeaufforderung zu drucken, wenn mit diesen Flags kompiliert?

    
Bart Silverstrim 19.05.2014, 16:56
quelle

3 Antworten

14

Das Problem ist, wenn ein Prozess mit einer ausführbaren Datei erstellt wird, die die Variable "subsystem" enthält In seinem PE-Header , der auf "Windows" gesetzt ist, hat der Prozess seine Drei Standardhandles geschlossen und es ist keiner Konsole zugeordnet - egal, ob Sie es von der Konsole aus ausführen oder nicht. (Wenn Sie eine ausführbare Datei ausführen, bei der das Subsystem von einer Konsole auf "console" not eingestellt ist, wird tatsächlich eine Konsole für diesen Prozess erstellt, und der Prozess wird an ihn angehängt - normalerweise wird er angezeigt als plötzlich ein Konsolenfenster auftauchte.)

Um also alles von einem GUI-Prozess unter Windows auf der Konsole auszugeben, müssen Sie diesen Prozess explizit mit der Konsole verbinden, die an den übergeordneten Prozess angehängt ist (falls vorhanden), wie erklärt hier zum Beispiel. Rufen Sie dazu die AttachConsole API-Funktion auf. Mit Go können Sie das Paket syscall verwenden:

%Vor%

Um wirklich vollständig zu sein, wenn AttachConsole() fehlschlägt, sollte dieser Code wahrscheinlich eine dieser beiden Routen annehmen:

  • Rufen Sie AllocConsole() auf, um ein eigenes Konsolenfenster zu erstellen.

    Es würde sagen, dass dies für die Anzeige von Versionsinformationen ziemlich nutzlos ist, da der Prozess normalerweise nach dem Drucken beendet wird, und die resultierende Benutzererfahrung wird ein Konsolenfenster sein, das auftaucht und sofort verschwindet; Machtanwender erhalten einen Hinweis, dass sie die Anwendung von der Konsole aus erneut ausführen sollten, aber Normalsterbliche werden es wahrscheinlich nicht schaffen.

  • Veröffentlichen Sie einen GUI-Dialog, der dieselben Informationen anzeigt.

    Ich denke, das ist genau das, was benötigt wird: Beachten Sie, dass die Anzeige von Hilfs- / Benutzungsmeldungen als Reaktion auf die Angabe eines Befehlszeilenarguments durch den Benutzer häufig mit der Konsole memly verbunden ist, aber dies ist kein Dogma zu folgen: Versuchen Sie zum Beispiel msiexec.exe /? an der Konsole laufen und sehen, was passiert.

kostix 19.05.2014, 18:05
quelle
1

Antwort oben war hilfreich, aber ach, es hat nicht für mich aus der Box funktioniert. Nach einigen zusätzlichen Recherchen kam ich zu diesem Code:

%Vor%

Der springende Punkt: Nach dem Zuweisen / Anfügen der Konsole muss das stdout-Handle aufgerufen werden, die Datei mit diesem Handle geöffnet und der os.Stdout-Variable zugewiesen werden. Wenn Sie stdin benötigen, müssen Sie dasselbe für stdin wiederholen.

    
Jumbleview 12.09.2016 04:04
quelle
0
___ answer39443208 ___

Antwort oben war hilfreich, aber ach, es hat nicht für mich aus der Box funktioniert. Nach einigen zusätzlichen Recherchen kam ich zu diesem Code:

%Vor%

Der springende Punkt: Nach dem Zuweisen / Anfügen der Konsole muss das stdout-Handle aufgerufen werden, die Datei mit diesem Handle geöffnet und der os.Stdout-Variable zugewiesen werden. Wenn Sie stdin benötigen, müssen Sie dasselbe für stdin wiederholen.

    
___ tag123go ___ Go ist eine Open-Source-Programmiersprache, die ursprünglich von Google entwickelt wurde. Es ist statisch typisiert, mit einer Syntax, die lose von C abgeleitet ist, und fügt automatische Speicherverwaltung, Typsicherheit, einige dynamische Typisierungsfunktionen, zusätzliche integrierte Typen wie Arrays variabler Länge und Schlüssel-Wert-Maps und eine große Standardbibliothek hinzu. ___ qstnhdr ___ Ausgabe an ein Befehlsfenster ausgeben, wenn die Golang-Anwendung mit -ldflags -H = windowsgui kompiliert wird ___ qstntxt ___

Ich habe eine Anwendung, die normalerweise im Hintergrund läuft, also kompiliere ich sie mit

%Vor%

Um die Version in der Befehlszeile zu überprüfen, wollte ich ein Flag -V an die Befehlszeile übergeben, um die Zeichenfolge, die die zu druckende Version enthält, an die Eingabeaufforderung zu erhalten und das Programm zu beenden. Ich habe das Flag-Paket und den Code hinzugefügt. Wenn ich es mit

teste %Vor%

... druckt die Version gut. Wenn ich die EXE kompiliere, wird sie einfach beendet und druckt nichts. Ich vermute, es ist das Kompilierungs-Flag, das bewirkt, dass es nicht auf die Konsole zugreift und meinen Text in den Bit-Bucket sendet.

Ich habe versucht, Variationen in stderr und stdout zu drucken, indem ich println und fprintf und os.stderr.write verwende, aber nichts erscheint von der kompilierten Anwendung. Wie sollte ich versuchen, eine Zeichenfolge an die Eingabeaufforderung zu drucken, wenn mit diesen Flags kompiliert?

    
___ answer23744350 ___

Das Problem ist, wenn ein Prozess mit einer ausführbaren Datei erstellt wird, die die Variable "subsystem" enthält In seinem PE-Header , der auf "Windows" gesetzt ist, hat der Prozess seine Drei Standardhandles geschlossen und es ist keiner Konsole zugeordnet - egal, ob Sie es von der Konsole aus ausführen oder nicht. (Wenn Sie eine ausführbare Datei ausführen, bei der das Subsystem von einer Konsole auf "console" not eingestellt ist, wird tatsächlich eine Konsole für diesen Prozess erstellt, und der Prozess wird an ihn angehängt - normalerweise wird er angezeigt als plötzlich ein Konsolenfenster auftauchte.)

Um also alles von einem GUI-Prozess unter Windows auf der Konsole auszugeben, müssen Sie diesen Prozess explizit mit der Konsole verbinden, die an den übergeordneten Prozess angehängt ist (falls vorhanden), wie erklärt hier zum Beispiel. Rufen Sie dazu die %code% API-Funktion auf. Mit Go können Sie das Paket %code% verwenden:

%Vor%

Um wirklich vollständig zu sein, wenn %code% fehlschlägt, sollte dieser Code wahrscheinlich eine dieser beiden Routen annehmen:

  • Rufen Sie %code% auf, um ein eigenes Konsolenfenster zu erstellen.

    Es würde sagen, dass dies für die Anzeige von Versionsinformationen ziemlich nutzlos ist, da der Prozess normalerweise nach dem Drucken beendet wird, und die resultierende Benutzererfahrung wird ein Konsolenfenster sein, das auftaucht und sofort verschwindet; Machtanwender erhalten einen Hinweis, dass sie die Anwendung von der Konsole aus erneut ausführen sollten, aber Normalsterbliche werden es wahrscheinlich nicht schaffen.

  • Veröffentlichen Sie einen GUI-Dialog, der dieselben Informationen anzeigt.

    Ich denke, das ist genau das, was benötigt wird: Beachten Sie, dass die Anzeige von Hilfs- / Benutzungsmeldungen als Reaktion auf die Angabe eines Befehlszeilenarguments durch den Benutzer häufig mit der Konsole memly verbunden ist, aber dies ist kein Dogma zu folgen: Versuchen Sie zum Beispiel %code% an der Konsole laufen und sehen, was passiert.

___
SM3 26.07.2017 05:52
quelle

Tags und Links