【问题标题】:No console output on Winforms project, works on Console projectWinforms 项目上没有控制台输出,适用于控制台项目
【发布时间】:2016-09-21 16:00:30
【问题描述】:

仅供参考,此问题已重新编辑以更简洁。

我正在使用 .NET(无论是 C# 还是 VB 中的帮助,都没有关系)。我有一个控制台应用程序,一些基本的东西:

using System;

namespace ConsolePrinter
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Output");
            Console.ReadLine();
        }
    }
}

在我的 Winforms 应用程序中,我需要重定向标准错误和标准输入,而不是标准输出。标准输出应继续显示在控制台窗口中。通过制作一个简单的 Winforms 项目并将上述控制台 EXE 作为 Process 对象启动,我仍然可以在调用的控制台中查看控制台的输出。一旦我重定向标准错误,输出就会从控制台窗口中消失,并且只显示一个空白控制台。

这是一个 Winforms 项目示例:

using System;
using System.Windows.Forms;
using System.Diagnostics;

namespace winformstest2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Process proc = new Process();
            proc.StartInfo.FileName = "ConsolePrinter.exe";
            //proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.UseShellExecute = false;

            proc.Start();
        }
    }
}

此代码按预期工作。取消注释该注释行提供了我正在谈论的错误。

我曾尝试将表单附加到控制台项目,但不幸的是我需要经常显示和隐藏控制台,因此将控制台应用程序作为一个进程启动是理想的。使用 Win32 API 也是一个想法,但用户不应该能够通过关闭控制台来关闭整个应用程序,AllocConsole() 和其他 Win32 API 调用将导致作为它们使用的副产品。

感谢您的帮助,谢谢!

【问题讨论】:

  • 不清楚发生了什么 - 当您启动命令行应用程序时,它是否以控制台窗口开始?拥有一个minimal reproducible example(控制台应用程序和一个小型 WinForms 应用程序 - 它只需要一个带有按钮的窗口来启动控制台应用程序......)肯定会有所帮助。
  • 这是stackoverflow.com/questions/4362111/… 的副本。虽然您必须将代码转换为 vb.net
  • @JonSkeet 这是一个输出到标准输出的 C++ 程序,没什么特别的。在控制台项目中,它直接输出到 .net 控制台窗口,使用 Winforms 它打开一个控制台但什么也不输出。
  • 与其告诉我们,不如尝试提供minimal reproducible example,以便我们自己复制它?
  • @FloatingKiwi:不,我不认为这是重复的——这是关于启动一个新进程,而不是将控制台附加到现有进程。

标签: c# .net vb.net winforms console


【解决方案1】:

事实证明,我很难重现这一点的原因是它根本不是 代码 问题 - 这是代码的运行方式。

如果您在调试器中运行程序,由于某种原因将RedirectStandardError 设置为true 会改变行为,如前所述。在调试器之外 - 从命令行、资源管理器或在 Visual Studio 中通过“开始而不调试”启动应用程序 - 输出会根据需要显示。

解决此问题的最简单方法是在需要输出时无需调试即可生存。这可能很尴尬,但它可能比其他方法更简单。

当然,另一种选择是重定向所有内容并在您的 WinForms 应用程序中构建您自己的迷你控制台。这将更整洁,更普遍的用户友好 - 没有额外的窗口在整个地方弹出 - 但更多的工作。如果这将成为许多人经常使用的长期应用程序,可能值得考虑,但不值得这样做。

【讨论】:

    【解决方案2】:

    Using this solution 应该可以工作。请注意,这是一个 Winforms 应用程序。

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace ConsoleExRun
    {
    
        class Program
        {
            [DllImport("kernel32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            static extern bool AllocConsole();
    
            static void Main(string[] args)
            {
                AllocConsole();
    
                Process proc = new Process();
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.FileName = "ping";
                proc.StartInfo.Arguments = "localhost";
                proc.StartInfo.RedirectStandardError = true;
                proc.StartInfo.RedirectStandardInput = true;
    
                proc.Start();
    
                Form f = new Form();
                Application.Run(f);
            }
        }
    }
    

    【讨论】:

    • 没有必要为这个进程分配控制台。
    • 我会向你投赞成票,但我已经经历过这个解决方案。关闭控制台会关闭整个程序,所以我还不如创建一个控制台项目并将表单附加到它。
    • @JonSkeet - 我的代码并不清楚,但这是一个 winforms 应用程序。对 AllocConsole 的调用允许标准输出出现在控制台窗口中。我已经修改了示例以使其更加明显
    • @FloatingKiwi:但没必要。请参阅gist.github.com/jskeet/dce5d4fdba80281eaf4365ce7ed8d80a - 一个启动控制台应用程序的 WinForms 应用程序,此时会出现控制台。基本上,OP 无故重定向输出,这就是问题所在。
    • @JonSkeet 我没有重定向输出
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 2012-06-20
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    相关资源
    最近更新 更多