简体   繁体   English

.NET应用程序作为Windows窗体或控制台应用程序运行

[英].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. 我希望从命令行以编程方式运行我的一个Windows窗体应用程序。 In preparation, I have separated the logic in its own class from the Form. 在准备中,我将自己类中的逻辑与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! Form1是我的形式, It works! string is just a placeholder for the actual logic. string只是实际逻辑的占位符。

Right now, when running this from within Visual Studio (with command line arguments), the phrase It works! 现在,当从Visual Studio中运行它(使用命令行参数)时,短语It works! is printed to the Output. 打印到输出。 However, when running the /bin/Debug/Program.exe file (or /Release for that matter) the application crashes. 但是,当运行/bin/Debug/Program.exe文件(或/ Release)时,应用程序崩溃。

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? 让我的逻辑类成为由两个独立应用程序加载的DLL会更有意义(即花费更少的开发人员时间)吗? 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. 如果检测到命令行参数,则需要P / Invoke AllocConsole()。 Check my answer in this thread for the required code. 此主题中检查我的答案以获取所需的代码。 AC# sample is further down the page. AC#样本位于页面下方。 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 . 将其更改为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). 是的,最好制作两个前端.exes(一个用于命令行,一个用于窗口)。

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. 主要原因是您必须为项目指定输出类型(命令行或Windows应用程序,您不能同时选择它们。

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). 因此,您必须始终使用Windows应用程序输出类型(这是Windows消息传递系统的开销,并没有为您提供“真正的”命令行)。

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)
{

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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