2008-12-03 8 views
6

Ich schreibe eine Anwendung, die entweder als Standard-WinForms-App oder im unbeaufsichtigten Modus über die Befehlszeile gestartet werden kann. Die Anwendung wurde unter Verwendung der VS2k5-Standard-WinForms-Vorlage erstellt.Ausgabe an die Befehlszeile, wenn über die Befehlszeile gestartet

Wenn die Anwendung über die Befehlszeile ausgeführt wird, möchte ich Informationen ausgeben, die vom Skript, das die Anwendung ausführt, erfasst werden können. Wenn ich dies direkt von Console.WriteLine() aus tue, wird die Ausgabe nicht angezeigt, obwohl sie durch Piping in eine Datei erfasst werden kann.

Auf der anderen Seite kann ich die Anwendung erzwingen, eine zweite Konsole zu öffnen, indem Sie eine P/Invoke auf AllocConsole() von kernel32. Das ist aber nicht das, was ich will. Ich möchte, dass die Ausgabe im selben Fenster erscheint, aus dem die Anwendung aufgerufen wurde.

Dies ist der ausgeprägte Code, der mir erlaubt, eine Konsole über die Befehlszeile Pop-up:

<STAThread()> Public Shared Sub Main() 

    If My.Application.CommandLineArgs.Count = 0 Then 
     Dim frm As New ISECMMParamUtilForm() 
     frm.ShowDialog() 
    Else 
     Try 
      ConsoleControl.AllocConsole() 
      Dim exMan As New UnattendedExecutionManager(ConvertArgs()) 
      IsInConsoleMode = True 
      OutputMessage("Application started.") 
      If Not exMan.SetSettings() Then 
       OutputMessage("Execution failed.") 
      End If 
     Catch ex As Exception 
      Console.WriteLine(ex.ToString()) 
     Finally 
      ConsoleControl.FreeConsole() 
     End Try 

    End If 

End Sub 

Public Shared Sub OutputMessage(ByVal msg As String, Optional ByVal isError As Boolean = False) 
    Trace.WriteLine(msg) 
    If IsInConsoleMode Then 
     Console.WriteLine(msg) 
    End If 

    If isError Then 
     EventLog.WriteEntry("ISE CMM Param Util", msg, EventLogEntryType.Error) 
    Else 
     EventLog.WriteEntry("ISE CMM Param Util", msg, EventLogEntryType.Information) 
    End If 

End Sub 

Antwort

2

Update 1:

Wie gesagt in Michael Burr Antwort, Raymond Chen kürzlich posted a short article about this. Ich bin froh zu sehen, dass meine Vermutung nicht völlig falsch war.

aktualisieren 0:

Haftungsausschluss: Diese "Antwort" ist meist Spekulation. Ich poste es nur, weil genug Zeit verstrichen ist, um festzustellen, dass nicht viele Leute die Antwort auf etwas haben, was wie eine fundamentale Frage aussieht.

Ich denke, dass die "Entscheidung", ob die Anwendung GUI oder Konsole zur Kompilierzeit und nicht zur Laufzeit gemacht wird. Also, wenn Sie Ihre Anwendung als GUI-Anwendung kompilieren, auch wenn Sie die GUI nicht anzeigen, ist es immer noch eine GUI-Anwendung und hat keine Konsole. Wenn Sie sich entscheiden, es als Konsolenanwendung zu kompilieren, dann werden Sie mindestens ein Konsolenfenster blinken lassen, bevor Sie in den GUI-Modus wechseln. Und ich weiß nicht, ob es in verwaltetem Code möglich ist.

Das Problem ist grundlegend, denke ich, weil eine Konsolenanwendung "Kontrolle" über die Calling Console-Anwendung nehmen muss. Und das, bevor der Code der untergeordneten Anwendung ausgeführt wird.

9

Raymond Chen vor kurzem veröffentlicht (einen Monat nach der Frage hier auf SO gebucht wurde) einen kurzen Artikel dazu:

How do I write a program that can be run either as a console or a GUI application?

Sie können nicht, aber man kann zu fälschen es versuchen.

Jede PE-Anwendung enthält in ihrem Header ein Feld , das angibt, welches -Subsystem für die Ausführung von ausgelegt wurde. Man kann sagen, IMAGE_SUBSYSTEM_WINDOWS_GUI markieren Sie sich als Windows-Anwendung GUI, oder Sie können sagen IMAGE_SUBSYSTEM_WINDOWS_CUI zu sagen, dass Sie eine Konsolenanwendung sind. Wenn Sie GUI-Anwendung sind, wird das Programm ohne eine Konsole ausgeführt.

Das Subsystem bestimmt, wie der Kernel die Ausführung Umgebung für das Programm vorbereitet.Wenn das Programm markiert ist in der Konsolen-Subsystem als ausgeführt wird, dann wird der Kernel wird das Programm der Konsole die Konsole seiner Eltern verbinden, eine neue Konsole zu schaffen, wenn die Eltern nicht hat eine Konsole. (Dies ist eine unvollständige Beschreibung, aber die Details sind nicht relevant für die Diskussion.) Auf der anderen Seite, wenn das Programm markiert wie als GUI-Anwendung ausgeführt wird, dann den Kernel wird das Programm ausführen ohne irgendeine Konsole überhaupt.

In diesem Artikel, den er von Junfeng Zhang zu einem anderen Punkt, die wie ein paar Programme (Visual Studio und ildasm) beschreiben dieses Verhalten implementieren:

How to make an application as both GUI and Console application?

In Visual Studio Fall gibt es eigentlich zwei Binärdateien: devenv.com und devenv.exe. Devenv.com ist eine Konsolen-App. Devenv.exe ist eine GUI-App. Wenn Sie devenv wegen der Win32-Prüfregel eingeben, wird devenv.com ausgeführt. Wenn keine Eingabe erfolgt, startet devenv.com devenv.exe und beendet sich selbst. Wenn es Eingaben gibt, behandelt devenv.com sie als normale Konsolen-App.

In ildasm Fall gibt es nur eine Binärdatei: ildasm.exe. Es wird zuerst als GUI-Anwendung kompiliert. Später wird editbin.exe verwendet, um es als Konsolen-Subsystem zu markieren. In seiner Hauptmethode bestimmt es, ob es als Konsolenmodus oder GUI-Modus ausgeführt werden muss. Wenn es als GUI-Modus ausgeführt werden muss, wird es als GUI-App neu gestartet.

In den Kommentaren zu Raymond Chen Artikel, laonianren hat dies Junfeng Zhang kurze Beschreibung, wie Visual Studio arbeitet hinzuzufügen:

devenv.com ist eine Konsole-Modus-Stub-Anwendung für allgemeine Zwecke. Wenn es ausgeführt wird, erstellt es drei Pipes, um die stdin, stdout und stderr der Konsole umzuleiten. Es findet dann seinen eigenen Namen (normalerweise devenv.com), ersetzt die ".com" durch ".exe" und startet die neue App (dh devenv.exe) mit dem Leseende der stdin-Pipe und den Schreibenden des stdout und Stderr-Rohre als Standard-Griffe. Dann sitzt es nur und wartet darauf, dass devenv.exe beendet wird, und kopiert Daten zwischen der Konsole und den Pipes.

Also obwohl devenv.exe eine GUI-App ist, kann es die "Eltern" -Konsole mit seinen Standard-Handles lesen und schreiben.

Und Sie könnten devenv.com für myapp.exe verwenden, indem Sie es in myapp.com umbenennen. Aber Sie können es nicht in der Praxis, weil es zu MS gehört.

Verwandte Themen