【发布时间】:2011-07-24 19:30:01
【问题描述】:
从类库中,我需要在运行时确定我是在 ASP.NET 应用程序中运行,还是在 WinForms/console 应用程序中运行。已经有severalotherquestionsasked 在这个主题上,但所有这些解决方案都需要添加对 System.Web 的引用。如果可能的话,在运行我的控制台和 WinForms 应用程序时,我不想将 System.Web 程序集加载到内存中,只是为了几千行代码中的一行。
【问题讨论】:
从类库中,我需要在运行时确定我是在 ASP.NET 应用程序中运行,还是在 WinForms/console 应用程序中运行。已经有severalotherquestionsasked 在这个主题上,但所有这些解决方案都需要添加对 System.Web 的引用。如果可能的话,在运行我的控制台和 WinForms 应用程序时,我不想将 System.Web 程序集加载到内存中,只是为了几千行代码中的一行。
【问题讨论】:
HostingEnvironment.IsHosted
【讨论】:
这是一个旧线程,但这是不是黑客的新答案。
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 应用程序。
【讨论】:
它可能看起来像一个黑客。它使用 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
【讨论】:
又一次破解:
如果您没有在独立的 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 ;
}
}
【讨论】:
您可以尝试基于 Assembly.GetEntryAssembly() 的方法。如以下评论中所述,如果当前代码在 Web 应用程序或服务的上下文中运行,则 GetEntryAssembly() 将返回 NULL。在 WinForm 或控制台应用等独立应用的情况下,它将返回一些非空引用。
由于评论,编辑更改了原始答案。
【讨论】:
Assembly.GetEntryAssembly() 为 Web 应用程序和 Web 服务返回 null。不过,好主意。
使用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?
【讨论】:
System.Diagnostics.Process.GetCurrentProcess().ProcessName 的值作为起点。但是,检查特定的返回值感觉有点 hacky。如果进程名称随 IIS 8 更改,我必须更新我的应用程序。我得考虑一下。
您链接到的一个问题包含一个answer,暗示Environment.UserInteractive。
您还可以尝试分析代码的StackTrace 以确定您是从哪里调用的。
【讨论】:
Environment.UserInteractive 返回 false,因此我不能将其作为区分 Web 应用程序与控制台应用程序的标志。我将尝试分析堆栈跟踪,看看我能想出什么。
您可以检查 System.Diagnostics.Process.GetCurrentProcess().ProcessName;。如果它以 aspnet 开头,那么它就是 asp.net。否则,桌面。
【讨论】: