如何运行显示控制台窗口或不基于参数参数的dotnet Core控制台应用程序?

Posted

技术标签:

【中文标题】如何运行显示控制台窗口或不基于参数参数的dotnet Core控制台应用程序?【英文标题】:How to run dotnet Core console application that shows the console window or not based on argument parameters? 【发布时间】:2021-03-20 07:52:08 【问题描述】:

我有一个单独的 dotnet-core GUI 应用程序,根据参数参数,它可能只显示 GUI 界面(使用 Avalonia 框架完成),或者如果它接收到一些特殊参数,那么它应该在控制台模式下工作并登录到控制台而不显示 GUI。 如果我使用<OutputType>WinExe</OutputType>,那么 GUI 显示正常,但应用程序永远不会登录到控制台(例如,使用 Console.WriteLine("some-text") 时)。 这意味着我需要使用 <OutputType>Exe</OutputType> 配置 csproj 以便能够登录到控制台任何内容,问题是在 GUI 模式下运行时,连同 GUI 应用程序窗口,会弹出另一个我想要的控制台窗口隐藏以仅显示 GUI。

在 dotnet full-framework 4.X 中,我能够创建在 1 个 exe 中执行这种双控制台/gui 模式的 WPF 应用程序。 一个可能的解决方案是,如果我可以在 GUI 模式下运行时隐藏控制台窗口,或者 Avalonia-UI/dotnet-core 有其他方法可以做到这一点。 有谁知道怎么做?

更新:以下是一些说明: 该应用有 2 种模式:

GUI 模式:如果您只是双击“App.exe”(不带 args 参数运行),那么应该会出现 GUI(并且只有 GUI,而不是 GUI 加上当前的另一个控制台窗口发生)。这通常可以通过将 csproj 设置为 <OutputType>WinExe</OutputType> 来完成,但这会使 Console.Write 函数在以下 Console Mode 中运行时不起作用。 控制台模式:如果高级用户尝试使用控制台中的某些应用程序功能自动执行某些操作,则该应用程序的行为应该像控制台应用程序一样,具有人们期望的所有功能,例如 app.exe -h显示可用命令,app.exe -v 显示版本等。这意味着显示一些手工制作的 GUI 窗口显示输出文本或在其他任何地方(如文件中)记录是不合适的。

它可以在 2 个单独的可执行文件中完成,但像我这样的人发现只是一个简单的 app.exe 文件的应用程序有一些好处。 这种双重行为的例子有很多,例如 VisualStudio 的 devenv.exe Nirsoft 应用程序。

【问题讨论】:

我不认为我理解这个问题。听起来您想将一些文本输出到没人能看到的窗口。那正确吗?有什么意义? 如果我理解,您希望根据应用接收的参数显示 GUI 或控制台。如果是这样,为什么不使用在 Console.WriteLine 中写入的 e 方法“LogToConsole”,如果您处于控制台模式,而如果您处于 GUI 模式则什么都不做? 您是否只对控制台感兴趣,只是为了记录信息?如果是这样,那么只记录到文件可能会更容易。 @JohnWu:当它作为 GUI 运行时,它不会写入控制台,并且不应显示控制台窗口。但是当它作为 ConsoleMode 运行时,它不应该显示 GUI,而只是写入控制台。问题是我找不到在运行时控制控制台窗口可见性的方法。如果我将 csproj 设置为WinExe,那么它适用于 GUI 模式而不适用于 ConsoleMode(因为它不会向控制台发送任何内容)。如果我将 csproj 设置为 Exe,那么它适用于 ConsoleMode,但不适用于 GUI 模式(因为它将打开 2 个窗口:1 个带有 GUI 和一个控制台窗口) “像 VisualStudio 的 devenv.exe” - 你的意思是 devenv.comdevenv.exe,前者是一个控制台应用程序,如果你在命令行,后者是 Windows GUI 应用程序?它们可能不会像您想象的那样实施。 【参考方案1】:

如果我没听错的话,另一方面,你想在特殊参数和 WinForms 应用程序上启动控制台。

首先你必须设置

<DisableWinExeOutputInference>true</DisableWinExeOutputInference>

在您的项目文件中。 See documentation

尝试将&lt;OutputType&gt; 设置回Exe 并将其添加到您的Program > Main

static class Program

    /// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    
        IntPtr h = GetConsoleWindow();

        // switch here to show or not show console window
        ShowWindow(h, 0);
        // ShowWindow(h, 1);

        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        // Hide your WinForms application manually if parameter is set
        var startup = new MainFormStartup();
        Application.Run(startup.CreateForm<MainWindow>());
    

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

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

我在本地尝试过

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
      <OutputType>Exe</OutputType>
      <TargetFramework>net5.0-windows</TargetFramework>
      <UseWindowsForms>true</UseWindowsForms>
      <DisableWinExeOutputInference>true</DisableWinExeOutputInference>
   </PropertyGroup>
</Project>

但老实说,我认为您应该使用共享库编译两个 exe 文件来完成一个控制台 exe 文件和一个 UI-exe 文件,fe。:

yourcode.csproj(你的业务逻辑)

yourapp-console.csproj(控制台应用程序:参考 yourcode.csproj) yourapp-ui.csproj(WinForms 应用程序:参考 yourcode.csproj)

【讨论】:

哇,非常感谢您的回复!我认为你完全理解了这个问题。 该解决方案并不完全完美,它有一些陷阱: - 如果您尝试从命令行以 GUI 模式打开 app.exe,则使用 ShowWindow() 方法隐藏控制台,它将隐藏您从中调用.\App.exe 的现有终端窗口! (使用 PowerShell 7.1 终端在 Windows 10 中测试) - 同样,当双击 App.exe 打开 GUI 时,控制台窗口会闪烁一瞬间,即使它是第一行,理想情况下它根本不会出现. 另一个主要问题是,即使它是一个 GUI 应用程序,也不意味着我使用的是仅 Windows 的框架,如 WinForms 或 WPF。我正在使用Avalonia-UI,它是跨平台(windows/Mac/Linux),但此解决方案仅适用于 windows。 @Lorazo 很抱歉,但这是我通过使用单一编译找到的唯一选择。这就是为什么我添加了 imo 更好的解决方案来编译成两个不同的 exe 文件,它们是共享代码库。

以上是关于如何运行显示控制台窗口或不基于参数参数的dotnet Core控制台应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据条件显示或不显示 NIB 创建的视图

通过参数显示控制台窗口

如何创建一个 C# 应用程序来决定自己是显示为控制台还是窗口应用程序?

如何定义带参数或不带参数调用的函数? [复制]

VMware Workstation上安装Ubuntu Server 12.04 窗口显示太小,如何变大?

强制 Http Get 接受带参数或不带参数的请求