C# 应用程序 GUI 和命令行

发布于 2024-12-01 15:04:10 字数 109 浏览 1 评论 0原文

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

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

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

I currently have an application with a GUI.

Would it be possible to use this same application from the commandline (without GUI and with using parameters).

Or do I have to create a separate .exe (and application) for the commandline tool?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柒夜笙歌凉 2024-12-08 15:04:10
  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...
    }
}

如果您的应用程序的结构尚未明确地进行静默处理(如果您的所有逻辑都塞入 WinForm 代码中),您可以 在 ala CharithJ 的答案中破解静默处理

由OP编辑
很抱歉劫持您的答案梅林。只是想为其他人提供这里的所有信息。

为了能够在 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. Edit your project properties to make your app a "Windows Application" (not "Console Application"). You can still accept command line parameters this way. If you don't do this, then a console window will pop up when you double-click on the app's icon.
  2. Make sure your Main function accepts command line parameters.
  3. Don't show the window if you get any command line parameters.

Here's a short example:

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

If your app isn't already structured to cleanly do silent processing (if all your logic is jammed into your WinForm code), you can hack silent processing in ala CharithJ's answer.

EDIT by OP
Sorry to hijack your answer Merlyn. Just want all the info here for others.

To be able to write to console in a WinForms app just do the following:

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());
        }
    }
}
倦话 2024-12-08 15:04: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.
         }
    }

In your program.cs class keep the Main method as it is but add string[] Args to the main form. For example...

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

In mainform.cs constructor

    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.
         }
    }
铁憨憨 2024-12-08 15:04:10

我是 C# 编程新手。但我根据 OP 和 Merlyn 的代码提示进行了即兴创作。我在使用他们的代码提示时遇到的问题是,当我通过双击 app.exe 调用 app.exe 或从 CMD 调用它时,参数长度不同。当 app.exe 从 CMD 作为 CLI 运行时,app.exe 本身将成为第一个参数。下面是我的临时代码,无论是在 GUI 中双击 app.exe 还是在 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 作为控制台输出窗口。但这对我的工作来说没问题。

I am new to c# programming. But I improvised the code hints from OP and Merlyn. The issue I faced when using their code hint was that the argument length is different when I call app.exe by double click on app.exe or when I call it from CMD. When app.exe is run as CLI from CMD then app.exe itself becomes the first arguments. Below is my improvised code which works satisfactory both as GUI double click of app.exe and as CLI from CMD.

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

    }

I hope this helps someone. The only drawback of my solution is when the app.exe is run as GUI, it will open a CMD as console output window. But this is OK for my work.

北座城市 2024-12-08 15:04:10

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

You may need to structure your Application as a Console Application, identify what you do on "Actions" - like clicking of the button - into separate class, include a form that can be shown if there were no command line arguments supplied, and handle events by routing them to the common methods in your "Action" class.

水溶 2024-12-08 15:04:10

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

但为了接受来自控制台窗口的命令,我想您将必须创建一个额外的线程来执行此操作。

I think it is possible, just set your subsystem to "console", you will see a console window as well as the GUI window.

But in order to accept commands from the console window, I guess you will have to create an extra thread to do it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文