2015-04-29 43 views
3

我谁应该两种模式执行的小应用程序:非UI或WPF窗口。它应该取决于命令行参数。如何动态地或者控制台应用程序或Windows应用程序

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

  1. 在WPF窗口模式下,WPF是要采取可视化日志的照顾,
  2. 在没有用户界面模式,我需要一个控制台显示日志。如果我的应用程序是从一个控制台(主要是cmd.exe)启动的,我想在不打开一个新的应用程序的情况下使用它。如果我的应用程序已经在控制台之外启动(双击explorer,CreateProcess,...),我需要创建一个新控制台来输出结果并等待一个Readkey关闭它。

我发现:

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

选择“Windows应用程序”,GetConsoleWindow()始终为0,我看不出如何重用以前的控制台。

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

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

+0

我认为它与WPF无关,但只在PE头和main/winmain中植入子系统。 – MuiBienCarlota

回答

7

在Winforms中这很容易,但它并不难。

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

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

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文件中定义)。

编辑这个错过你如何使用现有的控制台,我会当我弄清楚如何留在同一个控制台窗口中编辑的要求之一。

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

+0

我已经试验过这个解决方案。**你在这种情况下:“选择控制台应用程序”**。我们可以重用以前的控制台,但是当从资源管理器启动时,会在WPF主窗口下创建一个控制台。 – MuiBienCarlota

+0

@MuiBienCarlota我建议你尝试我所做的,当从Windows资源管理器启动时,你没有控制台窗口。我在发布之前进行了多次测试,没有出现窗口。您可能会对项目类型感到困惑,这是一个WPF应用程序,而不是控制台应用程序,所以在创建项目时不要选择控制台应用程序。 –

+0

我在你的第一个代码上做了它,我只是尝试了你的最后一个代码。从WPF项目开始,将您的Program类添加为新的主类,并将“启动对象”更改为主函数,将输出类型更改为“控制台应用程序”。我的程序从资源管理器启动时创建了一个控制台。 – MuiBienCarlota

相关问题