Wpf和命令行应用程序在同一个可执行文件中

问题描述 投票:6回答:3

我想有一个可执行文件,我可以用来打开图形应用程序(默认用例,单击.exe时),或者我可以用来运行命令行任务。

这可能吗?

如果是这样,我将如何修改我的app.xaml / app.xaml.cs,以便它只打开特定条件的图形视图(例如没有命令行参数)?

c# wpf command-line
3个回答
5
投票

首先,您必须使用WPF应用程序项目并更改app.xml,以便您可以覆盖窗口创建。

<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication1">
    <Application.Resources>

    </Application.Resources>
</Application>

请注意,这是缺少StartupUri属性。

然后,在你的App.xaml.cs上,你可以这样做:

public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            if (condition)
            {
                var window = new MainWindow();

                window.ShowDialog();
            }
            else
            {
                AllocConsole();
            }
        }

        [DllImport("Kernel32.dll")]
        static extern void AllocConsole();
    }

2
投票

您可以检查应用程序是否已从控制台执行。如果没有,您可以动态分配控制台:

if (GetConsoleWindow() == IntPtr.Zero)
   AllocConsole();

哪里

[DllImport("kernel32.dll")]
public static extern IntPtr GetConsoleWindow();

[DllImport("kernel32.dll")]
public static extern bool AllocConsole();

2
投票

@ BrunoKlein的回答将起作用,我的答案基于他的解决方案。引用@BrunoKlein,

首先,您必须使用WPF应用程序项目并更改app.xaml,以便您可以覆盖窗口创建。

<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication1">
    <Application.Resources>

    </Application.Resources>
</Application>

请注意,这缺少StartupUri属性。

现在,甚至更简单(至少在Visual Studio 2015中工作),转到项目属性,并将输出类型从Windows应用程序更改为控制台应用程序。这使得项目构建为控制台应用程序,但仍具有Windows应用程序的功能。

(此照片中会突出显示类库,而是选择控制台应用程序)

你做到了!完成。

现在,你的“主要”方法不是拥有void Main(string[] args),而是你自动生成的OnStautup类的App方法:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        string[] args = e.Args;

        if (SomeConditionBasedOnTheArgs(args))
        {
            // Instantiate view, call View.Show()
        }
        else
        {
            // Process the args
        }
    }
}

请注意,这个答案与@ BrunoKlein的答案之间的一个区别是,如果从explorer / start菜单/桌面运行它,这个将始终“显示”一个控制台,但如果从命令行运行,它将运行并指示其所有的标准输出到该控制台,就像任何普通控制台应用程序一样。

© www.soinside.com 2019 - 2024. All rights reserved.