I need to write a wrapper around a third party api that peruses message pumps and hence needs to be handled very differently depending on whether the wrapper is instantiated on a UI thread (such as within a wpf application) or not (such as a console application).
If it does not run on a UI thread then I need a dispatcher and implement my own message pump.
For that purpose I need to know whether the wrapper is instantiated within a wpf application or not. It is not enough to determine whether the instantiation happens on a UI thread or not (as even in a wpf application the thread on which the wrapper is instantiated might not be the UI thread).
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?
Thanks
I think you might be best off to have three separate packages.
To make it auto-select, you would need to have references to both WPF and WinForms in your package. Assuming worstcase, your package just made me import both into my console application. Others might consider importing WinForms into an WPF application worst case and another group of people might do WinForms because they cannot access WPF (and therefor you just cut them of from using your package altogether).
If no other answer satisfies your needs - you can use reflection to check if Application.Current
is null or not, without directly referencing WPF assemblies (and the same works with 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;
}
Note that this might load PresentationFramework
dll into current app domain, even in console application. If that is a problem for you - you can do the same by inspecting assemblies already loaded in app domain:
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;
}
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?
You could check whether there is a top-level window available:
if (Process.GetCurrentProcess().MainWindowHandle != IntPtr.Zero)
//WPF
MainWindowHandle
should return a handle provided that the WPF application has a main window.
You should also be able to use the native GetConsoleWindow function to determine whether you're in the context of a console application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With