开发者

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 is null 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 return null 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 and System.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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜