【问题标题】:WPF / Console Hybrid ApplicationWPF / 控制台混合应用程序
【发布时间】:2011-07-17 09:18:12
【问题描述】:

我正在编写一个可以在命令行上运行或使用 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());
    }
}

我将项目的输出类型设置为控制台应用程序,如果我尝试通过双击 exe 来执行它,我会弹出一个控制台窗口。如果未设置标志(通过命令参数传入),我不想向用户显示控制台窗口。

但是,如果我将项目的输出类型设置为 Windows 应用程序,双击行为很好,但是当我在控制台中运行它时,我没有得到控制台输出(Console.Writeline)

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    最好的办法是将实际执行工作的代码抽象到一个没有 UI 的单独类库中,然后创建两个应用程序一个控制台,另一个 WPF 调用它。

    控制台应用程序和 WPF 应用程序具有完全不同的应用程序模型,因此您不能在两个应用程序中重用相同的代码。

    拥有一个单独的类库可以让您做其他事情,例如在其他应用程序(如网站或客户端/服务器架构)中使用它。

    【讨论】:

      【解决方案2】:

      创建一个 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();
      }
      

      【讨论】:

        【解决方案3】:

        您可以通过以下示例执行以下步骤,有条件地启动您的 WPF 应用程序。

        1. 使用 STAThreadAttribute 声明的“Main”方法添加另一个入口点。这是 WPF 要求的。
        2. 在项目的“构建”属性下,选择“控制台应用程序”作为输出,并选择新的“主”方法作为应用程序的“启动对象”。

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

        【讨论】:

          【解决方案4】:

          我知道我参加聚会有点晚了,但我想我可以扔掉我的两分钱。您可以始终将其保留为控制台应用程序,然后根据此答案 (https://stackoverflow.com/a/3571628/1059953) 隐藏控制台。控制台显示片刻,然后消失并显示窗口。

          【讨论】:

            猜你喜欢
            • 2021-09-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-04
            • 1970-01-01
            相关资源
            最近更新 更多