C# 使单一程序支持以命令行程序或Windows应用程序两种形式执行

几个月前重拾C#写了一个小程序, 最近把它更新了下, 支持在命令行中运行, 这样就能配合脚本使用.

在开发途中遇到了一个小问题: 以Windows应用程序运行时, Console.WriteLine输出的结果是不可见的. 即以Windows应用程序形式运行时, 作为Console的实例并不存在, 所以程序无法输出任何信息.

解决的办法是在项目设置中, 将项目输出类型修改为”控制台应用程序”, 然后在以Windows应用运行时中使用Win32 API FreeConsole消除命令行窗口.

不过, 这个方法会产生一个新的问题: 在以Windows应用程序形式启动时, 会短暂出现一个命令行窗口.

其实类型为”Windows应用程序”时也可以用AllocConsole和AttachConsole这两个API达到类似的效果, 但由于我的程序需要跨平台到Linux上在命令行里运行, 所以我没有采用这种方法(调用DLL时会因找不到文件而报错).

Program.cs

using System;  
using System.Windows.Forms;

namespace Example{  
    internal sealed class Program{
        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        private static extern bool FreeConsole();

        [STAThread]
        private static void Main(string[] args){
            if(args.Length > 0){
                ConsoleMain(args);
            }else{
                try{
                    FreeConsole();
                }catch(Exception e){
                    Console.WriteLine(e.ToString());
                }finally{
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new MainForm());
                }
            }
        }

        private static void ConsoleMain(string[] args){
            Console.WriteLine(string.Join(", ", args));
        }
    }
}

实际运行效果

Powershell

Mono