2008-12-03 9 views
6

J'écris une application qui peut être démarrée soit en tant qu'application WinForms standard, soit en mode sans assistance à partir de la ligne de commande. L'application a été créée à l'aide du modèle standard WinForms VS 2k5. Lorsque l'application est exécutée à partir de la ligne de commande, je veux qu'elle produise des informations qui peuvent être capturées par le script exécutant l'application. Lorsque je le fais directement à partir de Console.WriteLine(), la sortie n'apparaît pas, bien qu'elle puisse être capturée en redirigeant vers un fichier. D'autre part, je peux forcer l'application à ouvrir une seconde console en effectuant un appel P/Invoke sur AllocConsole() à partir de kernel32. Ce n'est pas ce que je veux, cependant. Je veux que la sortie apparaisse dans la même fenêtre que celle à laquelle l'application a été appelée.Sortie vers la ligne de commande si elle est démarrée à partir de la ligne de commande

Voici le code saillant qui me permet de faire apparaître une console de la ligne de commande:

<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 

Répondre

2

Mise à jour 1:

Comme dit en réponse Michael Burr, Raymond Chen récemment posted a short article about this. Je suis heureux de voir que je n'ai pas totalement tort.

0 Mise à jour:

Avertissement: Cette "réponse" est la plupart du temps la spéculation. Je ne poste que parce que suffisamment de temps s'est écoulé pour établir que peu de gens ont la réponse à ce qui semble être une question fondamentale.

Je pense que la "décision" si l'application est gui ou la console est faite au moment de la compilation et non au moment de l'exécution. Donc, si vous compilez votre application en tant qu'application gui, même si vous n'affichez pas le gui, il s'agit toujours d'une application gui et n'a pas de console. Si vous choisissez de le compiler en tant qu'application console, vous aurez au minimum une fenêtre de console qui clignote avant de passer en mode "gui". Et je ne sais pas si c'est possible en code managé.

Le problème est fondamental, je pense, parce qu'une application console doit prendre le "contrôle" de l'application de la console d'appel. Et il doit le faire avant que le code de l'application enfant ne soit en cours d'exécution.

9

Raymond Chen récemment mis en ligne (un mois après la question a été publié ici sur le SO) un court article à ce sujet:

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

Vous ne pouvez pas, mais vous pouvez essayer de faire semblant.

Chaque application PE contient un champ dans son en-tête qui spécifie le sous-système il a été conçu pour fonctionner sous . Vous pouvez dire IMAGE_SUBSYSTEM_WINDOWS_GUI pour marquer vous comme une application Windows GUI, ou vous pouvez dire IMAGE_SUBSYSTEM_WINDOWS_CUI pour dire que vous êtes une application console. Si vous êtes une application graphique, alors le programme fonctionnera sans console.

Le sous-système détermine comment le noyau prépare l'environnement d'exécution pour le programme.Si le programme est marqué comme en cours d'exécution dans le sous-système de la console , le noyau se connecte à la console du programme pour la console de son parent, la création d'une nouvelle console si le parent n'a pas une console. (Ceci est une description incomplète, mais les détails ne sont pas pertinents à la discussion.) Sur la D'autre part, si le programme est marqué en cours d'exécution comme une application GUI, puis le noyau va exécuter le programme sans aucune console du tout.

Dans cet article, il pointe vers un autre par Junfeng Zhang qui explique comment un couple de programmes (Visual Studio et ildasm) mettre en œuvre ce comportement:

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

En VisualStudio cas, il y a en fait deux binaires: devenv.com et devenv.exe. Devenv.com est une application de console. Devenv.exe est une application graphique. Lorsque vous tapez devenv, en raison de la règle de sondage Win32, devenv.com est exécuté. S'il n'y a pas d'entrée, devenv.com lance devenv.exe, et se termine. S'il y a des entrées, devenv.com les gère comme une application console normale.

Dans le cas ildasm, il n'y a qu'un binaire: ildasm.exe. Il est d'abord compilé en tant qu'application graphique. Plus tard editbin.exe est utilisé pour le marquer comme sous-système de la console. Dans sa méthode principale, il détermine s'il doit être exécuté en mode console ou en mode GUI. Si besoin de fonctionner en mode interface graphique, il se relance comme une application graphique.

Dans les commentaires à l'article de Raymond Chen, laonianren a cette option pour ajouter à Junfeng Zhang brève description de comment Visual Studio Works:

devenv.com est une application stub mode console à usage général. Lorsqu'il s'exécute, il crée trois canaux pour rediriger stdin, stdout et stderr de la console. Il trouve alors son propre nom (habituellement devenv.com), remplace le ".com" par ".exe" et lance la nouvelle application (ie devenv.exe) en utilisant l'extrémité de lecture du tube stdin et les extrémités d'écriture de la sortie stdout et les tuyaux stderr comme les poignées standard. Ensuite, il s'assoit juste et attend de s'envoyer.exe et copie des données entre la console et les tuyaux.

Ainsi, même si devenv.exe est une application graphique, il peut lire et écrire la console "parent" en utilisant ses poignées standard.

Et vous pourriez utiliser devenv.com vous-même pour myapp.exe en le renommant en myapp.com. Mais vous ne pouvez pas en pratique parce qu'il appartient à MS.

Questions connexes