简体   繁体   中英

.NET app running as either Windows Form or as Console Application

I am looking to have one of my Windows Forms applications be run programmatically—from the command line. In preparation, I have separated the logic in its own class from the Form. Now I am stuck trying to get the application to switch back and forth based on the presence of command line arguments.

Here is the code for the main class:

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();
    }

where Form1 is my form and the It works! string is just a placeholder for the actual logic.

Right now, when running this from within Visual Studio (with command line arguments), the phrase It works! is printed to the Output. However, when running the /bin/Debug/Program.exe file (or /Release for that matter) the application crashes.

Am I going about this the right way? Would it make more sense (ie take less developer time) to have my logic class be a DLL that gets loaded by two separate applications? Or is there something entirely different that I'm not aware of?

Thanks in advance!

You'll need to P/Invoke AllocConsole() if you detect a command line argument. Check my answer in this thread for the required code. AC# sample is further down the page. Repeated here because I don't trust that crummy forum site:

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();
  }
}

Go to the project properties

On the Application tab you should see a dropdown list named Output Type . Change this to Console Application .

There, you have both a window and a console. Now your code with command argument should work.

Yes it would be better to make two frontend .exes (one for the command line and one for windowing).

The main reason is that you have to specify the output type for your project (either command line or Windows application and you can't select both.

So you would have to always use the Windows application output type (which comes at an overhead for the Windows messaging system and doesn't give you "real" command line).

Not sure if it makes a difference but instead of

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

you can instead put

static void Main(string[] args)
{

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM