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

17

我希望能够通过命令行对我的Windows窗体应用程序进行编程运行。为此,我已经将逻辑从窗体中分离出来,并放在了一个独立的类中。现在,我卡在了如何根据命令行参数的存在与否来切换应用程序上。

这是主类的代码:

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

这里的 Form1 是我的窗体,It works! 只是实际逻辑的占位符。

现在,在 Visual Studio 中运行此代码(带有命令行参数)时,将向输出打印出 It works!。但是,当从 /bin/Debug/Program.exe 文件(或 /Release 文件)中运行时,应用程序会崩溃。

我这样做正确吗?是否更明智(即需要更少的开发者时间)让我的逻辑类成为一个 DLL,由两个独立的应用程序加载?还是有其他我不知道的完全不同的方法?

提前感谢!


当应用程序崩溃时,您遇到了什么异常?此外,我认为应该是args.Length >= 1(或> 0),而不是> 1? - Nelson Rothermel
可能是重复的问题:如何在窗体应用程序中显示控制台输出/窗口? - Michael Freidgeim
4个回答

26

如果您检测到命令行参数,那么您需要使用P/Invoke AllocConsole()。请查看此线程中的我的答案以获取所需的代码。 C#示例在页面下方。这里再次发布是因为我不信任那个糟糕的论坛网站:

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
您还可以使用 FreeConsole: https://dev59.com/F0rSa4cB1Zd3GeqPWnmW#1787008 - adrianbanks
1
为什么不一开始就将其制作为控制台应用程序,然后引用窗口化的 Forms 组件呢? - Chris Dunaway
@Chris:只在需要时获取控制台,而不是一直存在。FreeConsole 是一个恶心的闪烁。 - Hans Passant

1

不确定是否有区别,但可以使用

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

你可以选择放置

static void Main(string[] args)
{

2
由于这不是解决问题的方案,因此应该将其作为注释而不是答案? - Peter

1

最好制作两个前端exe文件(一个用于命令行,一个用于窗口化)。

主要原因是您必须为项目指定输出类型(命令行或Windows应用程序),而不能同时选择两者。

因此,您必须始终使用Windows应用程序输出类型(这会增加Windows消息系统的开销,并且不会给您“真正”的命令行)。


1

进入项目属性

应用程序 选项卡中,您应该看到一个名为 输出类型 的下拉列表。将其更改为 控制台应用程序

现在,您既有窗口又有控制台。现在您的带命令参数的代码应该可以工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接