Determine if app is WinForms or WebForms
Is t开发者_开发问答here a way to determine if running app is WinForms or Web at runtime?
[Edit]
Is there actually a problem if I reference both System.Web
and System.Windows.Forms
in my class library?
[Summary] (so far)
What I've learned so far:
HttpContext.Current
isnull
if checked in an async thread, so it cannot reliably be used in a helper method.HttpRuntime.Cache
doesn't really help since I am not looking for the cached context at all (or am I missing something here?).- on the other hand,
System.Reflection.Assembly.GetEntryAssembly()
seems to returnnull
in web apps, and non null in WinForms. Should that be taken for granted? There should be more "hacks" like this, so which one to use? - referencing both
System.Web
andSystem.Windows.Forms
in a helper library should be fine, according to this thread.
In your edit you specify that your helper class is in a seperate assembly. If you want to avoid references and you have control over your app.config files you could put an
<add key="typeOfSystem" value="Forms|Web"/>
in your projects and access it with
ConfigurationManager.AppSettings["typeOfSystem"]
using ConfigurationManager along with its property AppSettings. Don't forget to add a reference to System.Configuration
in your project. Note that you get the AppSettings of the hosting application. By doing this you need to add a key in your parent application's app.config, or output some error or warning if it's not specified perhaps.
Check whether HttpContext.Current
is null
. If it is, it's not a webapp.
HttpContext.Current
can be null in a Web Application if it is doing asynchronous processing. From this thread HttpRuntime.Cache
might be a better thing to test.
Another way of doing this, is to look at the current process name.
using System.Diagnostics;
public class Helper
{
public static bool IsCurrentAppWeb()
{
return Process.GetCurrentProcess().ProcessName == "aspnet_wp";
}
}
This solution works for XP, the string to compare to varies by environment. When running VS in default debug mode, you will need to compare agains the name of the integrated testing server.
Not the prettiest solution, but it does allow you to omit references to either web or winforms assemblies.
Have a look at http://msdn.microsoft.com/en-us/library/system.diagnostics.process_members(v=VS.100).aspx for more details on the Process class.
For this question to make sense, you would have to have included references to both System.Web and System.Windows in your project. This in itself is (in my opinion) a bit of a code smell.
You are likely better off collecting the needed info in the calling method (which should be firmly in either the Web or WinForms domain) and passing this to whatever metods need this info as an argument.
[edit]
One way of doing this shown below. Still ugly, but it means only having to set the fact that you are in a webApp once.
public class Helper
{
public static bool IsCurrentAppWeb; //defaults to false
public bool TheActualHelpFullFunction()
{
if(Helper.IsCurrentAppWeb)
{
//do web specific things
}
else
{
//do things the non-web way.
//note that this does not tell you
//if you are currently running a WinForm or service or...
}
}
}
The AppDomain holds information of the associated config file. Since web apps have their config file named "web.config" and all others have "{app}.exe.config" this determines the type of application.
/// <summary> /// Extensions for the AppDomain class /// </summary> public static partial class AppDomainExtensions { /// <summary> /// Determines whether the specified app domain is a web app. /// </summary> /// <param name="appDomain">The app domain.</param> /// <returns> /// <c>true</c> if the specified app domain is a web app; otherwise, /// <c>false</c>. /// </returns> public static bool IsWebApp(this AppDomain appDomain) { var configFile = (string)appDomain.GetData("APP_CONFIG_FILE"); if (string.IsNullOrEmpty(configFile)) return false; return ( Path.GetFileNameWithoutExtension(configFile) ?? string.Empty ).Equals( "WEB", StringComparison.OrdinalIgnoreCase); } }
You have a convinient way to do it with framework property:
HostingEnvironment.IsHosted
Reference System.Web and add System.Web.Hosting namespace.
When IsHosted is true it means the host is web.
精彩评论