C#应用程序既有GUI又有命令行

Pee*_*Haa 46 c# user-interface command-line winforms

我目前有一个带GUI的应用程序.

是否可以从命令行使用相同的应用程序(没有GUI和使用参数).

或者我是否必须为命令行工具创建单独的.exe(和应用程序)?

Mer*_*ham 60

  1. 编辑项目属性以使您的应用程序成为"Windows应用程序"(而不是"控制台应用程序").您仍然可以通过这种方式接受命令行参数.如果不这样做,则双击应用程序图标时会弹出一个控制台窗口.
  2. 确保您的Main函数接受命令行参数.
  3. 如果获得任何命令行参数,请不要显示窗口.

这是一个简短的例子:

[STAThread]
static void Main(string[] args)
{
    if(args.Length == 0)
    {
        Application.Run(new MyMainForm());
    }
    else
    {
        // Do command line/silent logic here...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您的应用程序尚未构建为干净地进行静默处理(如果您的所有逻辑都被卡入WinForm代码中),那么您可以在CharicJ的答案中破解静默处理.

由OPIT编辑 抱歉劫持你的答案Merlyn.只想在这里为其他人提供所有信息.

为了能够在WinForms应用程序中写入控制台,只需执行以下操作:

static class Program
{
    // defines for commandline output
    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(int dwProcessId);
    private const int ATTACH_PARENT_PROCESS = -1;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // redirect console output to parent process;
        // must be before any calls to Console.WriteLine()
        AttachConsole(ATTACH_PARENT_PROCESS);

        if (args.Length > 0)
        {
            Console.WriteLine("Yay! I have just created a commandline tool.");
            // sending the enter key is not really needed, but otherwise the user thinks the app is still running by looking at the commandline. The enter key takes care of displaying the prompt again.
            System.Windows.Forms.SendKeys.SendWait("{ENTER}");
            Application.Exit();
        }
        else
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new QrCodeSampleApp());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 更新了你的答案.希望你不要介意:) (3认同)
  • `AttachConsole`的缺点是cmd调用将在控制台连接之前立即返回,因此在写入输出之前.这也是您在最后需要额外输入密钥的原因.如果要将输出管道或重定向到某处,则只会获得空输出.到目前为止,我还没有找到真正的解决方案.给定的解决方案不适用于我,但是最接近的解决方案. (3认同)

Cha*_*thJ 10

在program.cs类中保持Main方法不变,但添加string[] Args到主窗体.例如...

    [STAThread]
    static void Main(string[] Args)
    {
        ....
        Application.Run(new mainform(Args));
    }
Run Code Online (Sandbox Code Playgroud)

在mainform.cs构造函数中

    public mainform(string[] Args)
    {
        InitializeComponent();

        if (Args.Length > 0)
         {
             // Do what you want to do as command line application.
             // You can hide the form and do processing silently.
             // Remember to close the form after processing.
         }
    }
Run Code Online (Sandbox Code Playgroud)

  • 最好的方法 (3认同)
  • 缺点是您将无法在控制台窗口中看到任何输出,因为没有真正的控制台窗口连接到应用程序.`Console.WriteLine`不会产生任何可见的输出. (3认同)
  • +1; 但如果您作为控制台应用程序运行,甚至不要打扰`Application.Run`.隐藏窗口会起作用,但这是一个黑客:) (2认同)