如何确定 class 是在控制台应用程序还是 wpf 中实例化?

How to determine whether a class is instantiated within a console application or wpf?

我需要围绕第三方 api 编写一个包装器来细读消息泵,因此需要根据包装器是否在 UI 线程上实例化(例如在 wpf 应用程序中)或不(例如控制台应用程序)。

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

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

有什么方法可以确定我是在带有消息泵的 wpf 还是 windows 表单环境中,还是在必须实现自己的消息泵的控制台应用程序中?

谢谢

这可能有效:

public static void Main(string[] args)
{
    var application = Application.Current;
    Console.WriteLine($"Application is {(application == null ? "null": "not-null")}");
    Console.ReadKey();
}

需要引用 PresentationFramework,根据 Resharper,WindowsBase 和 System.Xaml

我认为您最好拥有三个独立的软件包。

要使其成为自动select,您需要在包中引用 WPF WinForms。假设最坏的情况,你的包只是让我将 both 导入到我的控制台应用程序中。其他人可能会考虑将 WinForms 导入到 WPF 应用程序中,最坏的情况是另一组人可能会导入 WinForms,因为他们无法访问 WPF(因此你只是让他们完全停止使用你的包)。

Is there any way I can figure out whether I am in a wpf or windows form environment with message pump or a console application where I have to implement my own message pump?

您可以检查是否有可用的顶级window:

if (Process.GetCurrentProcess().MainWindowHandle != IntPtr.Zero)
    //WPF

MainWindowHandle 应该 return 句柄,前提是 WPF 应用程序有主 window.

您还应该能够使用本机 GetConsoleWindow 函数来确定您是否处于控制台应用程序的上下文中。

如果没有其他答案满足您的需求 - 您可以使用反射来检查 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;
}

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

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;
}