如何将控制台输出添加到Windows wpf应用程序C#

时间:2011-09-26 17:19:35

标签: c# wpf windows-console

我想添加一个额外的控制台窗口来记录我的wpf应用程序的实时信息。 有什么想法??

巴约

答案: 项目属性中的控制台应用程序对我有用。 感谢的

5 个答案:

答案 0 :(得分:4)

不要这样做。

查看log4netNLog以将日志输出到文件中。通过正确配置这些框架,您可以获得更多功能(不同的日志级别,自动时间戳,每个记录行前面的自动类名)

当您使用它时,您可能还希望实现自己的外观,以便从其余代码中隐藏使用过的日志框架。这将允许您在需要时轻松更改日志记录框架。


如果要为程序同时拥有控制台和GUI窗口,可以通过将项目编译为console applicationcsc /target:exe)来实现此行为。但要注意:这肯定会导致可用性差,因为没有用户希望您的应用程序同时拥有控制台和GUI窗口。

答案 1 :(得分:2)

您可以调用AttachConsole WIN API函数,然后使用PInvoke调用此函数:

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

const uint ATTACH_PARENT_PROCESS = 0x0ffffffff;  // default value if not specifing a process ID

// Somewhere in main method
AttachConsole(ATTACH_PARENT_PROCESS);

答案 2 :(得分:1)

感谢您提出上述想法。以下是将控制台窗口添加到WPF应用程序所需的所有步骤。我们修改了WPF测试应用程序,以便在夜间测试过程中从命令行调用它。唯一的故障是当应用程序从控制台运行时,在调用FreeConsole()并退出应用程序后,命令提示符不会立即写入控制台窗口。 FreeConsole()函数似乎缺少对Flush()函数的调用,以强制将命令提示符写入控制台窗口。我的理由是控制台窗口向上/向下箭头历史记录可用,控制台接受另一个命令,但是当下一个应用程序运行并写入控制台窗口时,缺少的命令提示符随之写入。

  1. 在项目属性“应用程序”选项卡中,保留“输出类型= Windows应用程序”。
  2. 右键单击App.xaml并选择Properties
  3. 设置Build Action = Page
  4. 打开App.xaml.cs并修改App类,如下所示。

    public partial class App : Application
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool AttachConsole(uint dwProcessId);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool FreeConsole();
    
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern int GetConsoleTitle(System.Text.StringBuilder sbTitle, int capacity);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern bool SetConsoleTitle(string sTitle);
    
        [STAThread]
        public static int Main(string[] args)
        {
            Boolean hasExceptionOccured = false;
    
            System.Text.StringBuilder sbTitle = new System.Text.StringBuilder();
    
            try
            {
                // If the user does not provide any parameters assume they want to run in GUI mode.
                if (0 == args.Length)
                {
                    var application = new App();
                    application.InitializeComponent();
                    application.Run();
                }
                else
                {
                    const uint ATTACH_PARENT_PROCESS = 0x0ffffffff;  // Default value if not specifying a process ID.
    
                    // Attach to the console which launched this application.
                    AttachConsole(ATTACH_PARENT_PROCESS);
    
                    // Get the current title of the console window.
                    GetConsoleTitle(sbTitle, 64);
    
                    // Set the console title to the name and version of this application.
                    SetConsoleTitle(Global.thisProgramsName + " - v" + Global.thisProductVersion);
    
                    // Create a instance of your console class and call it’s Run() method.
                    var mainConsole = new ReportTester.MainConsole();
                    mainConsole.Run(args);                   
                }
            }
            catch (System.Exception ex)
            {
                System.Console.WriteLine(ex.Message);
                System.Console.WriteLine(ex.StackTrace);
                if (null != ex.InnerException)
                {
                    System.Console.WriteLine(ex.InnerException.Message);
                    System.Console.WriteLine(ex.InnerException.StackTrace);
                }
                hasExceptionOccured = true;
            }
            finally
            {
                // Since the console does not display the prompt when freed, we will provide one here.
                System.Console.Write(">");
    
                // Restore the console title.
                SetConsoleTitle(sbTitle.ToString());
    
                // Free the console.
                FreeConsole();
            }
    
            return (hasExceptionOccured ? 1 : 0);
        }
    }
    

答案 3 :(得分:0)

要求不明确。听起来,似乎唯一真正的要求是能够重定向标准输出。似乎不需要控制台窗口。

在空白(新的)WPF应用程序中,将以下内容添加到Loaded事件中:

export class AppComponent implements AfterViewInit {

  ngAfterViewInit() {
    this.linkExternalStyleSheet('assets/styles/custom-theme.css');
  }

  linkExternalStyleSheet(externalStyleSheetUrl: string) {
    const overrideStyleSheet: any = document.getElementById('extStyleLink');
    if (overrideStyleSheet) {
      overrideStyleSheet.href = externalStyleSheetUrl;
    } else {
      const link = document.createElement('link');
      link.id = 'extStyleLink';
      link.rel = 'stylesheet';
      link.type = 'text/css';
      link.media = 'screen';
      link.href = externalStyleSheetUrl;
      document.getElementsByTagName('head')[0].appendChild(link);
    }
  }
}

然后从命令提示符处执行程序,并将标准输出重定向到文件。输出将在文件中。标准输入可以以相应的方式重定向。

对于标准IO是我们无法控制的要求的情况,这可能非常有用。我们可以将GUI窗口与标准IO结合在一起。

答案 4 :(得分:0)

如果您希望程序同时具有控制台和GUI窗口,则可以通过将项目编译为控制台应用程序来实现。

只需转到项目属性,然后将输出类型更改为console application

现在,当您运行时,将同时获得WPF窗口和控制台窗口。