如何动态地成为控制台应用程序或Windows应用程序 [英] How to be dynamically either console application or Windows Application

查看:112
本文介绍了如何动态地成为控制台应用程序或Windows应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小型应用程序,应以两种模式执行:非UI或WPF窗口。它应该取决于命令行参数。

I have a small application who should be executed in two modes: non UI or WPF Window. It should depend on command line arguments.

在每种模式下,我需要显示一些反馈日志:

In each mode, I need to show some feedback log:


  1. 在WPF窗口模式下,WPF将负责可视化日志,

  2. 在无UI模式下,我需要一个控制台来显示日志。如果我的应用是从控制台(主要是cmd.exe)启动的,则我希望在不打开新应用的情况下使用它。如果我的应用程序是在控制台外部启动的(双击资源管理器,单击CreateProcess,...),则需要创建一个新控制台以输出结果并等待Readkey将其关闭。

我发现:

  • how I can create a new console: How to open/close console window dynamically from a wpf application?,
  • how to get current console windows handle to show/hide it: Show/Hide the console window of a C# console application

我知道我可以在项目属性中静态选择 Windows应用程序或控制台应用程序。

And I know I can statically choose between "Windows Application" or "Console Application" in project property.

选择 Windows应用程序时,GetConsoleWindow()始终为0,我看不到如何重用

Choosing "Windows Application", GetConsoleWindow() is always 0 and I don't see how to reuse a previous console.

选择控制台应用程序,我可以重复使用以前的控制台,但是当从WPF窗口模式下的资源管理器启动时,会在WPF主窗口下创建一个控制台

Choosing "Console Application", I can reuse a previous console but when started from explorer in WPF Window mode, a console is created under my WPF main window.

问题是:应用程序如何真正动态?在WPF窗口模式下,只有WPF窗口(没有控制台)甚至在非UI中,只有一个控制台(启动一个控制台或新创建的控制台)。

The question is: how can an application be really dynamic? Either in WPF Window mode, with only a WPF windows (and no console at all) or in non UI, with only one console (starting one or a new created one).

推荐答案

在Winforms中容易得多,但并不难。

It was a lot easier in Winforms, but its not too hard.

从WPF应用程序项目开始(而不是具有WPF窗口的控制台应用程序项目)。

Start off with a WPF Application Project (not a console application project with WPF windows).

在根目录中创建一个新的Program.cs类,添加以下代码:

Create a new Program.cs class in the root directory, add the following code:

class Program
{
    [DllImport("Kernel32")]
    public static extern void AllocConsole();

    [DllImport("Kernel32")]
    public static extern void FreeConsole();

    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(uint dwProcessId);

    [STAThread]
    public static void Main(string[] args)
    {
        bool madeConsole = false;
        if (args.Length > 0 && args[0] == "console")
        {

            if (!AttachToConsole())
            {
                AllocConsole();
                Console.WriteLine("Had to create a console");
                madeConsole = true;
            }

            Console.WriteLine("Now I'm a console app!");
            Console.WriteLine("Press any key to exit");
            Console.ReadKey(true);

            if (madeConsole)
                FreeConsole();
        }
        else
        {
            WpfApplication1.App.Main();
        }
    }


    public static bool AttachToConsole()
    {
        const uint ParentProcess = 0xFFFFFFFF;
        if (!AttachConsole(ParentProcess))
            return false;

        Console.Clear();
        Console.WriteLine("Attached to console!");
        return true;
    }

}

现在您拥有控制台应用程序或WPF应用程序。在属性中,将启动对象设置为 Program.Main 方法。在上面的示例中,WpfApplication1.App.Main是旧的启动对象(在App.xaml.cs文件中定义)。

Now you have a console app or a WPF app. In the Properties, set the start up object as the Program.Main method. In the example above, WpfApplication1.App.Main is the old start up object (defined in the App.xaml.cs file).

编辑错过了您对使用现有控制台的要求之一,一旦确定如何保留在同一控制台窗口中,我将立即对其进行编辑。

Edit this misses one of your requirements about using the existing console and I will edit it as soon as I figure out how to stay in the same console window.

新编辑现在可以使用现有控制台了!

New Edit Now works to use the existing console!

这篇关于如何动态地成为控制台应用程序或Windows应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆