如何确定一个类是在控制台应用程序或wpf中实例化的?

Mat*_*olf 8 c# wpf dispatcher ui-thread

我需要编写一个围绕第三方api的包装器,它会使用消息泵,因此根据是否在UI线程(例如在wpf应用程序中)实例化包装器(例如控制台应用程序),需要对其进行非常不同的处理).

如果它不在UI线程上运行,那么我需要一个调度程序并实现我自己的消息泵.

为此,我需要知道包装器是否在wpf应用程序中实例化.仅确定实例化是否发生在UI线程上是不够的(即使在wpf应用程序中,实例化包装器的线程可能不是UI线程).

有什么办法我可以弄清楚我是在一个带有消息泵或控制台应用程序的wpf或windows窗体环境中我必须实现自己的消息泵吗?

谢谢

nvo*_*igt 9

我认为你可能最好有三个独立的包.

要使其自动选择,您需要在包中引用WPF WinForms.假设最坏情况下,你的包只是让我的进口在我的控制台应用程序.其他人可能会考虑将WinForms导入到最坏情况的WPF应用程序中,而另一组人可能会执行WinForms,因为他们无法访问WPF(因此您只是将它们从完全使用您的程序包中删除).


Evk*_*Evk 6

如果没有其他答案满足您的需求 - 您可以使用反射来检查是否Application.Current为null,而无需直接引用WPF程序集(与WinForms相同):

private static bool IsWpfApplication() {
    var type = Type.GetType("System.Windows.Application, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
    if (type == null)
        return false;
    var currentProp = type.GetProperty("Current", BindingFlags.Public | BindingFlags.Static);
    if (currentProp == null)
        return false;
    return currentProp.GetValue(null, new object[0]) != null;
}
Run Code Online (Sandbox Code Playgroud)

请注意PresentationFramework,即使在控制台应用程序中,这也可能会将dll 加载到当前应用程序域 如果这对您来说是个问题 - 您可以通过检查已在app域中加载的程序集来执行相同的操作:

private static bool IsWpfApplication2() {
    var wpfAsm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(c => c.GetName().Name == "PresentationFramework"); 
    if (wpfAsm == null)
        return false;
    var type = wpfAsm.GetType("System.Windows.Application");
    if (type == null)
        return false;
    var currentProp = type.GetProperty("Current", BindingFlags.Public | BindingFlags.Static);
    if (currentProp == null)
        return false;
    return currentProp.GetValue(null, new object[0]) != null;
}
Run Code Online (Sandbox Code Playgroud)