C# 确定应用程序是WinForms还是WebForms

C# 确定应用程序是WinForms还是WebForms,c#,winforms,webforms,C#,Winforms,Webforms,有没有办法确定运行中的应用程序是WinForms还是Web [编辑] 如果我在类库中同时引用System.Web和System.Windows.Forms,是否确实有问题 [摘要](到目前为止) 到目前为止,我学到的是: HttpContext.Current如果在异步线程中选中,则为null,因此无法在助手方法中可靠地使用它HttpRuntime.Cache没有真正的帮助,因为我根本没有寻找缓存的上下文(或者我在这里遗漏了什么?) 另一方面,System.Reflection.Assembl

有没有办法确定运行中的应用程序是WinForms还是Web

[编辑]

如果我在类库中同时引用
System.Web
System.Windows.Forms
,是否确实有问题

[摘要](到目前为止)

到目前为止,我学到的是:

  • HttpContext.Current
    如果在异步线程中选中,则为
    null
    ,因此无法在助手方法中可靠地使用它
    HttpRuntime.Cache
    没有真正的帮助,因为我根本没有寻找缓存的上下文(或者我在这里遗漏了什么?)
  • 另一方面,
    System.Reflection.Assembly.GetEntryAssembly()
    在web应用程序中似乎返回
    null
    ,在WinForms中则返回非null。这是理所当然的吗?应该有更多像这样的“黑客”,那么使用哪一个呢
  • 据介绍,在助手库中同时引用
    System.Web
    System.Windows.Forms
    应该可以

检查
HttpContext.Current
是否为
null
。如果是,则它不是Web应用程序。

HttpContext。如果Web应用程序正在进行异步处理,则当前的
可以为空。从
HttpRuntime.Cache
中进行测试可能更好。

为了让这个问题有意义,您必须在项目中同时包含对System.Web和System.Windows的引用。这本身(在我看来)有点代码味道

您最好在调用方法中收集所需的信息(应该在Web或WinForms域中),并将此信息作为参数传递给任何需要此信息的metods

[编辑]

一种方法如下所示。仍然很难看,但这意味着你只需要设置一个事实,即你在一个webApp中存在一次

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

另一种方法是查看当前进程名称

using System.Diagnostics;

public class Helper
{
  public static bool IsCurrentAppWeb()
  {
    return Process.GetCurrentProcess().ProcessName == "aspnet_wp"; 
  }
}
此解决方案适用于XP,要比较的字符串因环境而异。在默认调试模式下运行VS时,需要重新比较集成测试服务器的名称

这不是最漂亮的解决方案,但它允许您省略对web或winforms程序集的引用


查看有关Process类的更多详细信息。

在编辑中,您指定帮助器类位于单独的程序集中。如果你想避免引用,并且你可以控制app.config文件,你可以放置一个

<add key="typeOfSystem" value="Forms|Web"/>

与它的属性一起使用。不要忘记在项目中添加对
System.Configuration
的引用。请注意,您可以获得托管应用程序的AppSettings。执行此操作时,您需要在父应用程序的app.config中添加一个密钥,或者如果没有指定,则输出一些错误或警告。

AppDomain保存相关配置文件的信息。由于web应用程序的配置文件名为“web.config”,而所有其他应用程序的配置文件名为“{app}.exe.config”,这决定了应用程序的类型

//
///AppDomain类的扩展
/// 
公共静态部分类AppDomainExtensions
{
/// 
///确定指定的应用程序域是否为web应用程序。
/// 
///应用程序域。
/// 
///如果指定的应用程序域是web应用程序,则为,
///错。
/// 
公共静态bool IsWebApp(此AppDomain AppDomain)
{
var configFile=(字符串)appDomain.GetData(“APP_CONFIG_文件”);
if(string.IsNullOrEmpty(configFile))返回false;
返回(
Path.GetFileNameWithoutExtension(配置文件)??string.Empty
).等于(
“网络”,
对照组(例);
}
}

使用框架属性可以方便地完成此操作:

HostingEnvironment.IsHosted
参考System.Web并添加System.Web.Hosting命名空间


当IsHosted为true时,表示主机是web。

谢谢!您还可以查看我更新的问题以了解更多详细信息吗?正如M.Smith在下面所写的,HttpContext.Current在执行异步操作时为空,因此它并不总是有效。问题的关键是在共享程序集中有公共逻辑(它将引用它需要引用的任何内容),因此,调用程序集只需要引用共享程序集。无意冒犯,但您发布的代码是代码气味的一个典型例子,而且比添加两个引用更糟糕。类不应公开公共字段,以供其他客户端更改。如果您需要将一些信息传递给方法,请将其作为参数传递(如
bool TheActualHelpFunction(bool isCurrentAppWeb)
),不要期望调用方在调用方法之前更改一系列标志。我同意,我的示例并不更好。我想避免的是让程序集根据其运行的环境更改其行为。这对您来说不是问题,但它可能会成为下一个继承代码的人的问题。他可能不知道行为会随着运行环境的变化而变化。阅读你的另一个问题()可以让我更清楚地了解你的意图。我只能对这一意图表示赞赏。
/// <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);
    }
}
HostingEnvironment.IsHosted