WPF + 反射 + 控制台输出不起作用



我开发了一个WPF应用程序。此应用程序使用外部可执行托管程序集(dll 或 exe(来扩展其机会,如插件。 我通过反射使用该外部程序集:

Dim asm As Assembly = Assembly.LoadFrom("myPlugin.exe")
Dim t As Type = (From tp As Type In asm.GetTypes
Where tp.Name.Contains("Module1")
Select tp).First
Dim entryMethod As MethodInfo = t.GetMethod("EntryMethod")
Dim o As Object = entryMethod.Invoke(Nothing, Nothing)

所有这些组件都具有轻微的功能,并且可以相对较快地完成工作,没有问题。但是其中一个插件有更连续的工作,我需要显示插件的工作进度。 所以我决定将当前进度打印到控制台中:

Console.WriteLine(progress)

插件程序集的类型是控制台应用程序。此方法由我的"插件"可执行文件直接调用。当我自己运行它时 - 控制台可见并打印进度。但是当从 WPF 应用程序加载的程序集时 - 控制台不可见,我看不到控制台输出。

我已经尝试使用从">kernel32.dll"导入的函数">AllocConsole"从我的 WPF 甚至插件程序集显示控制台窗口:

<DllImport("kernel32.dll")>
Public Function AllocConsole() As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

稍后在代码中,但在首次在控制台中打印之前:

AllocConsole()

控制台窗口现在可见,但仍为空白。

所以问题是:是否可以从 .NET 类库中输出到控制台?又如何?

这取决于您希望查看控制台输出的原因,最佳选择是什么。

您可以在新流程中"重定向标准输出"。 StreamWriter sw = new StreamWriter(fs(; Console.SetOut(

如果可以修改加载的 dll 的源,则可以重构代码,使其不会直接写入控制台。 这样,您就可以在控制台应用程序中调用代码,将其配置为写入控制台。

在 WPF 中,可以提供写入内存流的不同实现。

这实际上取决于您为什么要查看打印到控制台的内容。

如果是用于调试应用程序,则应将原始娃娃更改为使用日志记录框架。(示例log4net(已经可以处理。

如果您尝试使用控制台应用程序为您工作,则应将需要调用的代码更改为不与控制台交互的"纯函数"。这样,就可以直接从 wpf 应用调用函数。 如果无法修改源代码,您可以创建一个子进程,并通过进程启动信息结构为"STDIN"和"STDOUT"提供内存流

好的,我终于找到了解决方案。

1( 在项目的属性中将 WPF 项目类型设置为"控制台 WPF 应用程序"。

2( 加载主窗口后,通过调用"kernel32.dll"库的"FreeConsole(("方法关闭控制台窗口。

3( 在 WPF 中使用类库之前,请调用"kernel32.dll"的"AllocConsole(("方法。

4( 当不需要控制台窗口时,通过"FreeConsole(("隐藏控制台窗口。

步骤 3 和 4 在需要时重复。

我建议以某种方式编写辅助类,包装"kernel32.dll"函数的调用以使用控制台窗口。

最新更新