【问题标题】:Determine whether running in ASP.NET or WinForms/console without System.Web确定是否在没有 System.Web 的情况下在 ASP.NET 或 WinForms/console 中运行
【发布时间】:2011-07-24 19:30:01
【问题描述】:

从类库中,我需要在运行时确定我是在 ASP.NET 应用程序中运行,还是在 WinForms/console 应用程序中运行。已经有severalotherquestionsasked 在这个主题上,但所有这些解决方案都需要添加对 System.Web 的引用。如果可能的话,在运行我的控制台和 WinForms 应用程序时,我不想将 System.Web 程序集加载到内存中,只是为了几千行代码中的一行。

【问题讨论】:

    标签: .net asp.net winforms


    【解决方案1】:
    HostingEnvironment.IsHosted
    

    MSDN Docs

    【讨论】:

    • 这需要System.Web,我在我确实不想想参考的问题中明确说明了这一点。
    • 抱歉没有详细阅读问题。 ;-) 但是这个解决方案可以满足我的需要,而且我没有在任何地方看到它。所以我想我会把它扔出去。
    【解决方案2】:

    这是一个旧线程,但这是不是黑客的新答案。

    private bool IsExe()
    {
      var domainManager = AppDomain.CurrentDomain.DomainManager;
      if (domainManager == null) return false;
    
      var entryAssembly = domainManager.EntryAssembly;
      if (entryAssembly == null) return false;
    
      return entryAssembly.Location.EndsWith(".exe", StringComparison.OrdinalIgnoreCase);
    }
    

    这不会告诉您应用程序是否是 ASP.Net,但它会告诉您这是控制台还是 WinForms 应用程序,这与此处的大多数其他答案相反。例如,如果这是一个 OWIN 应用程序,IsExe 方法将返回 false,即使这不是 ASP.Net 应用程序。

    【讨论】:

      【解决方案3】:

      它可能看起来像一个黑客。它使用 DomainManager 类型的 Current AppDomain。还要检查AppDomainManager

      public static class AspContext
      {
          public static bool IsAspNet()
          {
              var appDomainManager = AppDomain.CurrentDomain.DomainManager;
              return appDomainManager != null && appDomainManager.GetType().Name.Contains("AspNetAppDomainManager");
          }
      }
      

      或者你可以使用this other answer on SO

      【讨论】:

        【解决方案4】:

        又一次破解:

        如果您没有在独立的 exe 中运行,System.Configuration.ConfigurationManager.OpenExeConfiguration 会引发带有特定消息的 ArgumentException。您可以使用该事实以这种方式进行检查:

        bool notAnExe = false ;
        try
        {
            // see if we're running in an exe.
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        }
        catch(ArgumentException aex)
        {
            if(aex.Message == "exePath must be specified when not running inside a stand alone exe.")
            {
                notAnExe = true ;
            }
        }
        

        【讨论】:

        【解决方案5】:

        您可以尝试基于 Assembly.GetEntryAssembly() 的方法。如以下评论中所述,如果当前代码在 Web 应用程序或服务的上下文中运行,则 GetEntryAssembly() 将返回 NULL。在 WinForm 或控制台应用等独立应用的情况下,它将返回一些非空引用。

        由于评论,编辑更改了原始答案。

        【讨论】:

        • Assembly.GetEntryAssembly() 为 Web 应用程序和 Web 服务返回 null。不过,好主意。
        • 那么这是一个可能的解决方案;如果 GetEntryAssembly() 返回 null,则表示您处于 Web 环境中,而如果返回某些内容,则表示您处于某个独立环境中。
        • 不能保证它是网络。文档:“[I]如果非托管应用程序创建用 C# 编写的 COM 组件的实例,则从 C# 组件调用 GetEntryAssembly 方法返回 null,因为进程的入口点是非托管代码而不是托管程序集。 "
        • 如果从 MS Test 调用它也返回 null,因为它不是可执行文件
        【解决方案6】:

        使用System.Diagnostics.Process.GetCurrentProcess().ProcessName

        如果您正在运行 ASP.NET,则程序集 will be named thusly:

        • 如果您运行的是 IIS 6.0 或 IIS 7.0,则名称为 w3wp.exe。

        • 如果您运行的是早期版本的 IIS,则名称为 aspnet_wp.exe。

        另一个想法:如何使用 AppDomain.CurrentDomain.GetAssemblies() API 测试进程/应用程序域是否存在 System.Web.dll?

        【讨论】:

        • GetExecutingAssembly() 返回包含当前执行代码行的程序集。对于位于被各种类型的应用程序引用的 DLL 中的类库,无论哪个应用程序引用它,它总是相同的。
        • 我喜欢这个,因为它很简单,而且我已经将System.Diagnostics.Process.GetCurrentProcess().ProcessName 的值作为起点。但是,检查特定的返回值感觉有点 hacky。如果进程名称随 IIS 8 更改,我必须更新我的应用程序。我得考虑一下。
        • 是的,这是一个 hack。实际上,当我试图确定我正在创建的自定义控件是处于设计模式还是运行时时,我首先遇到了它。为此,我必须检查所有者进程是否是 IDE。 Control.DesignMode 属性实际上不起作用。也就是说,对冲你的赌注是个好主意。您是否检查过任何其他替代方案,例如检测某些核心 ASP.NET DLL 是否在同一进程中加载​​?这应该是一个可靠的线索。
        • @Bill:检查我上面的“另一个想法”编辑。它可能对你有用。虽然需要注意的是,如果您正在运行的应用程序使用 Web API,则可能会加载程序集......
        • 我还没有测试过这个,它可能有点矫枉过正,但你可以通过反射将 System.Web 程序集加载到一个单独的应用程序域中,然后在完成后将其销毁吗?这至少不是真正的 hack,并且可以在整个过程中将程序集作为应用程序的一部分加载。
        【解决方案7】:

        您链接到的一个问题包含一个answer,暗示Environment.UserInteractive

        您还可以尝试分析代码的StackTrace 以确定您是从哪里调用的。

        【讨论】:

        • 当控制台应用程序从 Windows 任务计划程序运行时,Environment.UserInteractive 返回 false,因此我不能将其作为区分 Web 应用程序与控制台应用程序的标志。我将尝试分析堆栈跟踪,看看我能想出什么。
        • 此测试在 Windows 服务中也会失败
        【解决方案8】:

        您可以检查 System.Diagnostics.Process.GetCurrentProcess().ProcessName;。如果它以 aspnet 开头,那么它就是 asp.net。否则,桌面。

        【讨论】:

        • 这不适用于所有版本的 ASP.NET
        猜你喜欢
        • 1970-01-01
        • 2016-04-30
        • 1970-01-01
        • 2011-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        • 2018-07-13
        相关资源
        最近更新 更多