简体   繁体   English

WPF /控制台混合应用程序

[英]WPF / Console Hybrid Application

I writing an application what can either be run on the command line, or with a WPF UI. 我编写的应用程序可以在命令行上运行,也可以使用WPF UI运行。

[STAThread]
static void Main(string[] args)
{
    // Does magic parse args and sets IsCommandLine to true if flag is present
    ParseArgs(args);     

    if(IsCommandLine)
    {
        // Write a bunch of things to the console
    }
    else
    {
        var app = new App();
        app.Run(new Window());
    }
}

I set the project's Output type to Console Application, I get a console window that popups if I try to execute it by double-clicking the exe. 我将项目的输出类型设置为控制台应用程序,如果我尝试通过双击exe来执行它,我会弹出一个控制台窗口。 I don't want to show the console window to the user if the flag is not set (passed in via command args). 如果未设置标志(通过命令args传入),我不想向用户显示控制台窗口。

However, if I set the project's Output type to Windows Application, the double-click behaviour is fine, but when I run it in the console, I get no console output (Console.Writeline) 但是,如果我将项目的输出类型设置为Windows应用程序,双击行为很好,但是当我在控制台中运行它时,我没有控制台输出(Console.Writeline)

Your best bet would be to abstract out the code that actually does the work to a separate class library that has no UI and then create two applications one Console, the other WPF that call this. 你最好的选择是将实际完成工作的代码抽象到一个没有UI的独立类库,然后创建两个应用程序,一个控制台,另一个调用它的WPF。

A console application and an WPF application have entirely different application models so you can't reuse the same code in both applications. 控制台应用程序和WPF应用程序具有完全不同的应用程序模型,因此您无法在两个应用程序中重用相同的代码。

Having a separate class library allows you do other things like use it in other applications such as a web site or client/server architecture. 拥有一个单独的类库允许您执行其他操作,例如在其他应用程序(如网站或客户端/服务器体系结构)中使用它。

Create a WPF app and add the following code to your App class: 创建一个WPF应用程序并将以下代码添加到您的App类:

public partial class App
{
    protected override void OnStartup(StartupEventArgs e)
    {
        if (e.Args.Length > 0)
        {                
            List<string> lowercaseArgs = e.Args.ToList().ConvertAll(x => x.ToLower());
            if (AttachConsole(ATTACH_PARENT_PROCESS))
            {
                // your console app code                

                Console.Write("\rPress any key to continue...");
                Console.ReadKey();
                FreeConsole();
            }
            Shutdown();
        }
        else
        {
            base.OnStartup(e);
        }
    }

    private const int ATTACH_PARENT_PROCESS = -1;

    [DllImport("kernel32", SetLastError = true)]
    private static extern bool AttachConsole(int dwProcessId);

    [DllImport("kernel32.dll")]
    private static extern bool FreeConsole();
}

You can conditionally start your WPF application by performing the following steps with the sample below. 您可以通过以下示例执行以下步骤来有条件地启动WPF应用程序。

  1. Add another entry point with the 'Main' method declarated with STAThreadAttribute. 使用STAThreadAttribute声明的'Main'方法添加另一个入口点。 This is required by WPF. 这是WPF所要求的。
  2. Under your project's 'Build' properties, choose 'Console Application' as your output and your new 'Main' method as the application's 'Startup Object'. 在项目的“构建”属性下,选择“控制台应用程序”作为输出,选择新的“主”方法作为应用程序的“启动对象”。

     using System; public static class Program { [STAThreadAttribute] public static void Main() { Console.WriteLine("What now?"); Console.ReadKey(true); App.Main(); } } 

I know I'm a little late to the party, but figured I could toss in my two cents. 我知道我参加聚会有点晚了,但我觉得我可以投入两分钱。 You could always keep it as a console application, and then hide the console as per this answer ( https://stackoverflow.com/a/3571628/1059953 ). 您可以始终将其保留为控制台应用程序,然后根据此答案隐藏控制台( https://stackoverflow.com/a/3571628/1059953 )。 There is a moment of the console being displayed, then it disappears and the window shows up. 有一个控制台显示的时刻,然后它消失,窗口出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM