C#混合cli和win-form应用程序

本文关键字:win-form 应用程序 cli 混合 | 更新日期: 2023-09-27 18:28:30

我一直在研究如何创建一个混合winform和CLI应用程序。。。我最初的应用程序是Winforms,现在我正在添加CLI……它似乎可以工作,但有一些问题我想弄清楚如何解决,但一直未能解决,可能是因为我缺乏C#的经验。

如果我在VS中的输出类型设置为"windows应用程序",并使用下面的代码,我就可以为GUI运行winform部分,而且从命令行我可以给它提供参数,它就可以工作了,至少它输出我在其中编码的控制台,我有一个单独的c#类文件,它有我的主代码,所以它与winform GUI和我最终的cli代码是分开的,它们都只会将用户输入提供给另一个"main"c#类。。无论如何,这是代码。

     [STAThreadAttribute]
    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(int dwProcessId);
    private const int ATTACH_PARENT_PROCESS = -1;
    static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new form_Main());
        }
        else
        {   
            AttachConsole(ATTACH_PARENT_PROCESS);
            cli_main cli = new cli_main();
            cli.start_cli(args);
        }
    }

好吧,它在gui中工作,我可以访问我的菜单并创建不同的获胜形式,当我点击按钮执行操作时,我会得到以下异常:

用户代码未处理System.Threading.ThreadStateExceptionMessage=在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式。请确保Main函数上标记了STAThreadAttribute。只有当调试器附加到进程时,才会引发此异常。

如果我把输出类型改为"控制台应用程序",它在cli和GUI中的所有方式都能完美工作,但当它打开winform/GUI部分时,我会得到一个丑陋的CMD窗口,它不会消失。。这是我使用的代码,基本上就是我在添加上述代码之前开始使用的代码。

    static void Main(string[] args)
    {

        if (args.Length == 0)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new form_Main());
        }
        else
        {            
            cli_main cli = new cli_main();
            cli.start_cli(args);
        }
    }

再一次,由于我对C#缺乏了解,我希望有人能给我一个解决方案。我更愿意将该应用程序保留为输出"控制台应用程序",并找到一种方法来隐藏在我启动winform/gui部分时打开的控制台。。??提前谢谢。

C#混合cli和win-form应用程序

您执行了错误消息中所说的操作吗?

确保您的Main函数上已标记STAThreadAttribute

在粘贴的代码中,STAThread属性没有标记Main方法,而是标记AttachConsole外部函数。把它移到应该的地方,你就不会有任何问题。

如果你的应用程序是一个控制台应用程序,如果还没有连接控制台窗口,它会自动获得一个控制台窗口。这就是使它成为控制台应用程序的意义所在。您可以在运行时使用FindWindowShowWindow(SW_HIDE)来隐藏它,但它仍会在屏幕上短暂闪烁。

如果您计划大部分时间从现有控制台窗口启动应用程序,则应将其保留为控制台应用程序,因为默认情况下它将继承父进程的控制台窗口。如果您计划从UI快捷方式或其他非控制台进程启动应用程序,您可能应该将其设置为Windows应用程序,并根据需要分配控制台。

感谢所有人,但对以前的模式进行了一些更改

它是这样工作的:

static void Main(string[] args)
{
    // Test pattern
    args = new string[] { "-flag1", "value1", "-flag2", "value2", "-flag3", "value3" };
    if (args.Length == 0)
        MainWinApp();
    else
        MainCLI(args);
}
[STAThread]
static MainWinApp()
{
    // Your code for start GUI application
}
[STAThreadAttribute]
static void MainCLI(string[] args)
{
    // Your code for CLI application
}