我开发了一个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应用程序加载的程序集 - 控制台不可见时,我看不到控制台输出。
我尝试过使用导入功能" AllocConsole "来自我的WPF的show console窗口,甚至尝试使用插件程序集。来自" kernel32.dll ":
<DllImport("kernel32.dll")>
Public Function AllocConsole() As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
后来在代码中,但在第一次在控制台中打印之前:</ p>
AllocConsole()
现在可以看到控制台窗口,但它仍然是空白的。
所以问题是:是否可以从.NET类库中输出到控制台?如何?
答案 0 :(得分:1)
这取决于您希望看到控制台输出最佳选择的原因。
您可以重定向标准输出&#39;在你的新过程中。 StreamWriter sw = new StreamWriter(fs); Console.SetOut(
如果你可以修改你加载的dll的源代码,你可以重构代码,这样它就不会直接写入控制台。这样,您可以调用配置它的控制台应用程序中的代码来写入控制台。
在WPF中,您可以提供写入内存流的不同实现。
这实际上取决于您为什么要查看打印到控制台的内容。
如果要调试应用程序,则应更改原始玩偶以使用日志框架。 (示例log4net)已经可以处理。
如果您尝试使用控制台应用程序为您工作,您需要调用的代码应更改为纯粹的功能&#39;没有与控制台交互。这样你就可以直接从wpf app调用该函数。如果无法修改源代码,您可以创建子进程并为“STDIN&#39;”提供内存流。和&#39; STDOUT&#39;通过流程启动信息结构
答案 1 :(得分:0)
好的,我终于找到了解决方案。
1)将WPF项目类型设置为&#34;控制台WPF应用程序&#34;在项目的属性中。
2)加载主窗口后,通过调用&#34; FreeConsole()&#34;关闭控制台窗口。 &#34; kernel32.dll&#34;的方法库。
3)在WPF中使用类库之前,请调用&#34; AllocConsole()&#34; &#34; kernel32.dll&#34;。
的方法4)当不需要控制台窗口时,通过&#34; FreeConsole()&#34;隐藏控制台窗口。
步骤3和4在需要时重复。
我建议写一些帮助类,包装调用&#34; kernel32.dll&#34;用于控制台窗口的功能。