2010-05-11 5 views
12

Ich bin auf der Suche nach einer meiner Windows Forms-Anwendungen programmgesteuert ausgeführt werden - von der Befehlszeile aus. Zur Vorbereitung habe ich die Logik in ihrer eigenen Klasse von der Form getrennt. Jetzt stehe ich fest und versuche, die Anwendung basierend auf dem Vorhandensein von Befehlszeilenargumenten hin und her zu schalten. Hier.NET App läuft entweder als Windows Form oder als Konsolenanwendung

ist der Code für die Hauptklasse:

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     string[] args = Environment.GetCommandLineArgs(); 
     if (args.Length > 1) // gets passed its path, by default 
     { 
      CommandLineWork(args); 
      return; 
     }   

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 

    private static void CommandLineWork(string[] args) 
    { 
     Console.WriteLine("It works!"); 
     Console.ReadLine(); 
    } 

wo Form1 meine Form ist und die It works! Zeichenfolge ist nur ein Platzhalter für die eigentliche Logik.

Wenn Sie das jetzt in Visual Studio (mit Befehlszeilenargumenten) ausführen, wird der Ausdruck It works! in die Ausgabe gedruckt. Wenn Sie die Datei /bin/Debug/Program.exe (oder/Release für diese Angelegenheit) ausführen, stürzt die Anwendung jedoch ab.

Gehe ich den richtigen Weg? Wäre es sinnvoller (d. H. Weniger Entwicklerzeit), wenn meine Logikklasse eine DLL ist, die von zwei separaten Anwendungen geladen wird? Oder gibt es etwas ganz anderes, das mir nicht bewusst ist?

Vielen Dank im Voraus!

+0

Welche Ausnahme erhalten Sie, wenn die App abstürzt? Außerdem nehme ich an, es sollte args.Length> = 1 (oder> 0) statt> 1 sein? –

Antwort

22

Sie müssen P/Invoke AlloConsole(), wenn Sie ein Befehlszeilenargument finden. Überprüfen Sie meine Antwort in this thread für den erforderlichen Code. Ein C# -Beispiel befindet sich weiter unten auf der Seite. Wiederholte hier, weil ich nicht, dass crummy Forum-Website vertrauen:

using System; 
using System.Windows.Forms; 

namespace WindowsApplication1 { 
    static class Program { 
    [STAThread] 
    static void Main(string[] args) { 
     if (args.Length > 0) { 
     // Command line given, display console 
     AllocConsole(); 
     ConsoleMain(args); 
     } 
     else { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
     } 
    } 
    private static void ConsoleMain(string[] args) { 
     Console.WriteLine("Command line = {0}", Environment.CommandLine); 
     for (int ix = 0; ix < args.Length; ++ix) 
     Console.WriteLine("Argument{0} = {1}", ix + 1, args[ix]); 
     Console.ReadLine(); 
    } 

    [System.Runtime.InteropServices.DllImport("kernel32.dll")] 
    private static extern bool AllocConsole(); 
    } 
} 
+1

Sie können auch 'FreeConsole' verwenden: http://stackoverflow.com/questions/1786840/c-is-it-possible-to-have-a-single-application-behave-as-console-or-windows-appl/1787008 # 1787008 – adrianbanks

+1

Warum nicht einfach eine Konsolenanwendung erstellen und dann auf die Forms-Assembly für die Fensterung verweisen? –

+0

@Chris: bekomme eine Konsole nur auf Anfrage, nicht immer. FreeConsole ist ein * böser * Flash. –

1

Ja, es wäre besser, zwei Frontend. Exits zu machen (eins für die Kommandozeile und eins für die Fensterung).

Der Hauptgrund dafür ist, dass Sie den Ausgabetyp für Ihr Projekt (entweder Befehlszeile oder Windows-Anwendung angeben, und Sie beide nicht auswählen können.

So würden Sie immer die Windows-Anwendung Ausgabetyp verwenden müssen (das kommt zu einem Overhead für das Messaging-System von Windows und nicht geben Sie „echte“ Kommandozeile).

1

nicht sicher, ob es einen Unterschied macht, aber statt

static void Main() 
{ 
     string[] args = Environment.GetCommandLineArgs(); 

Sie stattdessen

setzen können
+2

Da dies keine Lösung für das Problem ist, sollte dies ein Kommentar sein, keine Antwort? – Peter

0

Sind Sie es wirklich als eine echte Konsole App laufen gehen mit dem Benutzer zu fragen, um Daten usw. eingeben, oder sind Sie einfach es geht zu starten mit einigen Argumenten, damit es aus einer Batch-Datei oder einer geplanten Aufgabe oder ähnlichem ausgeführt werden kann?

Wenn es eine echte Konsolen-App ist, würde ich Foxfire zustimmen, dass es sich wahrscheinlich lohnt, 2 exe-Dateien zu haben, aber ansonsten würde ich es als eine exe behalten. Ich habe viele davon ohne irgendwelche Probleme gemacht.

Was ist die genaue Ausnahme, die auftritt?

0

Gehen Sie zu den Projekteigenschaften

Auf der Anwendung Registerkarte Sie eine Dropdown-Liste Ausgabetyp genannt sehen sollte. Ändern Sie diese Einstellung in Konsolenanwendung.

Dort haben Sie sowohl ein Fenster und eine Konsole. Jetzt sollte dein Code mit Befehlsargument funktionieren.

Verwandte Themen