WPF+反射+控制台输出不工作

WPF+反射+控制台输出不工作,wpf,reflection,console-application,Wpf,Reflection,Console Application,我开发了一个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 A

我开发了一个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应用程序控制台加载的程序集不可见时,我无法看到控制台输出

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

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


所以问题是:是否可以从.NET类库中输出到控制台?怎么做

这取决于您为什么希望看到控制台输出的最佳选择

您可以在新进程中“重定向标准输出”。 StreamWriter sw=新的StreamWriterfs; 放线

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

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

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

如果是为了调试应用程序,则应将原始玩偶更改为使用日志框架。已经可以处理的示例log4net


如果您试图使用控制台应用程序为您工作,则需要调用的代码应更改为“纯函数”,而不与控制台交互。这样,您就可以直接从wpf应用程序调用该函数。如果源代码无法修改,您可以创建一个子进程,并通过进程开始信息结构为“STDIN”和“STDOUT”提供内存流。好的,我终于找到了解决方案

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

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

3在WPF中使用类库之前,请调用kernel32.dll的alloconsole方法

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

步骤3和4在需要时重复


我建议编写帮助类,包装调用kernel32.dll函数,以便使用控制台窗口。

您能提供一个重现该问题的最小工作示例吗。而不是在评论中,把它放到你的问题中。它使阅读和阅读变得更容易understand@thehennyy我已经将信息附加到我的post.DLL中,它用于扩展主WPF应用程序,如插件。主应用程序无法进行MIDI,这就是为什么我实现了dinamic库的附加功能。这个dll做得很好,应该向控制台报告进度。但控制台是不可见的,不会显示其进度。实际上,我可能会使用以下技巧:在dll中创建属性进度,并在处理任务的关键点更新它。在我的WPF应用程序中,我将定期读取进度属性值。不是最优雅的解决方案,但它似乎很有用。不,最后一个想法不起作用。。。我只能在调用方法之前和方法完成工作之后读取Progress属性值。。。这一过程正在继续。
<DllImport("kernel32.dll")>
Public Function AllocConsole() As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
AllocConsole()