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

时间:2011-08-26 00:03:51

标签: c# winforms user-interface command-line

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

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

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

6 个答案:

答案 0 :(得分:56)

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

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

    如果您的应用程序尚未构建为干净地执行静默处理(如果您的所有逻辑都被卡入WinForm代码中),则可以hack silent processing in ala CharithJ's answer

    OP编辑 抱歉劫持你的答案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());
            }
        }
    }
    

答案 1 :(得分:10)

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

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

在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.
         }
    }

答案 2 :(得分:0)

评论不足。我想添加到公认的解决方案中,当使用mingw调用程序时,不需要将[DllImport(“ kernel32.dll”)]写入控制台,看来这是Windows / DOS问题。

答案 3 :(得分:0)

我是C#编程的新手。但是我即兴创作了OP和Merlyn的代码提示。我在使用其代码提示时遇到的问题是,当我双击app.exe或从CMD调用app.exe时,参数长度是不同的。当从CMD作为CLI运行app.exe时,app.exe本身将成为第一个参数。下面是我的即兴代码,既可以作为app.exe的GUI双击,也可以作为CMD的CLI来工作。

[STAThread]
    static void Main(/*string[] args*/)
    {
        string[] args = Environment.GetCommandLineArgs();
        Console.WriteLine(args.Length);
        if (args.Length <= 1)
        {
            //calling gui part
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new ACVSAppForm());
        }
        else
        {
            //calling cli part                
            string opt = args[1];
            //Console.WriteLine(args[0]);                
            if(opt == "LastBuild")
            {
                if(args.Length == 3)
                {
                    var defSettings = Properties.Settings.Default;
                    defSettings.CIBuildHistPath = args[2];
                }
                else
                {
                    //
                }
                CIBuildParser cibuildlst = new CIBuildParser();
                cibuildlst.XMLParser();
            }
        }

    }

我希望这对某人有帮助。我的解决方案的唯一缺点是当app.exe作为GUI运行时,它将打开CMD作为控制台输出窗口。但这对我的工作来说还可以。

答案 4 :(得分:-1)

您可能需要将您的应用程序构建为控制台应用程序,将您在“操作”上执行的操作(如单击按钮)标识到单独的类中,包括可在未提供命令行参数时显示的表单,并通过将事件路由到“Action”类中的常用方法来处理事件。

答案 5 :(得分:-2)

我认为这是可能的,只需将子系统设置为“控制台”,您将看到一个控制台窗口以及GUI窗口。

但是为了接受来自控制台窗口的命令,我猜你将不得不创建一个额外的线程来完成它。