ASP.NET Core 6.0+:如何获取当前(区分大小写)的IIS网站名称?
ASP.NET Core 6.0+: How to get the current (case-sensitive) IIS Website Name?
我正在尝试获取我在 IIS 中托管的 ASP.NET 6 应用程序的名称。我需要的正是这个带有适当大小写的名称:
在 .NET Framework 4.8 中,此名称由 HttpRequest.ApplicationPath 提供,返回时带有正确的大小写(如在 IIS 中配置的那样,而不是在即将到来的请求的 URL 中)。但是,它在 .NET 6 中不存在。
我试过了:
HttpContext.Request.PathBase
,但它 returns 与请求 URL 中的路径完全相同,而不是 IIS 中的路径
- 正在注入
IServerAddressesFeature
和 IWebHostEnvironment
,但其中 none 包含来自 IIS 且大小写正确的名称
IServerAddressesFeature
,但也没有在此处找到任何相关内容
- 获取服务器变量:
IServerVariablesFeature serverVars = HttpContext.Features.Get<IServerVariablesFeature>()
然后是 IIS 站点名称:string iis_version = serverVars["INSTANCE_NAME"]
(参见文档 here),但它 returns 大写字母的应用程序名称( MYSITE.WEB
)
有谁知道如何获取此网站在 IIS 中配置的名称(使用正确的大小写)?
长话短说:
- 使用
APPL_MD_PATH
server-variable。
- 这包含 IIS 配置数据库应用程序路径字符串。 (据我所知,“MD”代表“Meta-database”)。
- 引用文档:
https://docs.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms524602(v=vs.90)?redirectedfrom=MSDN
"APPL_MD_PATH
- Retrieves the metabase path of the application."
像这样:
// This code assumes HttpContext is available, such as in a Middleware method or `Controller` subclass.
using Microsoft.AspNetCore.Http;
String? iisMetabasePath = httpContext.GetServerVariable("APPL_MD_PATH");
// or (long-form):
String? iisMetabasePath = HttpContextServerVariableExtensions.GetServerVariable( httpContext, "APPL_MD_PATH" );
然后 trim-off /LM/W3SVC/
部分。
请注意,当您 运行 您的代码在 IIS 之外时,例如使用 ASP.NET Core 的开发服务器,所有 IIS-specific 数据,例如 "APPL_MD_PATH"
都不会可用,因此请确保您也在处理这种情况。
原始研究:ApplicationRoot
发生了什么事?
是时候 bust-out ILSpy 了...
HttpRequest.ApplicationPath
是 HttpRuntime.AppDomainAppVirtualPath
.
HttpRuntime.AppDomainAppVirtualPath
是 VirtualPath.GetVirtualPathStringNoTrailingSlash(HttpRuntime._theRuntime._appDomainAppVPath)
.
HttpRuntime._theRuntime._appDomainAppVPath
设置在HttpRuntime.Init()
.
HttpRuntime.Init()
从 HttpRuntime.GetAppDomainString(".appVPath"))
设置 _appDomainAppVPath
。
- “AppDomain 字符串”很小 可序列化 标量 values that are associated with each
AppDomain
.
- 一般来说,.NET Framework 中的 ASP.NET(又名
System.Web
)会为 IIS 中的每个 Application Scope 创建一个新的 AppDomain
。
- 当然还有 AppDomains no-longer exist in .NET Core and later。
- 所以让我们找出
".appVPath"
的 String
值从何而来...
System.Web.Hosting.ApplicationManager::PopulateDomainBindings
集 dict.Add(".appVPath", appVPath.VirtualPathString)
- “域绑定”在此上下文中指的是 AppDomain 绑定:与 DNS domain-names 或
Host
header 完全无关IIS 中的绑定。是的,超载的术语。
PopulateDomainBindings
被 System.Web.Hosting.ApplicationManager::CreateAppDomainWithHostingEnvironment
调用。
- 它得到
virtualPath: VirtualPath.Create(appHost.GetVirtualPath())
。
appHost.GetVirtualPath()
是 IApplicationHost.GetVirtualPath()
。
- 有 2 个 in-box 实现:
System.Web.Hosting.ISAPIApplicationHost
和 System.Web.Hosting.SimpleApplicationHost
。我们对 ISAPIApplicationHost
. 感兴趣
ISAPIApplicationHost
从 IAppManagerAppDomainFactory.Create
方法中 String appId
和 String appPath
的 运行time 参数获取其 virtualPath。
- 而
IAppManagerAppDomainFactory
是IIS直接使用的COM接口。
- 剧情变厚了...
- 此时我迷路了 through the legacy IIS 6 ISAPI documentation,寻找
IAppManagerAppDomainFactory
的原始 COM 定义的踪迹,但找到了 empty-handed。
- 它可能由
webengine4.dll
处理,它是一个本机 DLL,我现在没有时间 bust-out Ghidra...
- 我确实注意到 ISAPI 请求 entrypoint method
HttpExtensionProc
(and its LPEXTENSION_CONTROL_BLOCK
parameter) 不 包含 IIS 应用程序范围 AppId
或虚拟路径,它让我感到惊讶 - 但最重要的是:这表明该值可能来自 GetServerVariable
或 ServerSupportFunction
回调....
- 然而,这可能是浪费时间 IIS 6 是 不是 IIS7+ 并且 IIS7+ 的接口 no-longer 称为“ISAPI”,但仅称为“IIS Native-Code API”(这是我最近看到的最平淡无奇的API名字了...)。
- 因此,从 “IIS Native-Code API” 文档 I quickly found the
IWpfApplicationInfoUtil::GetApplicationPropertiesFromAppId
method (here "WPF" means "Worker Process Framework”开始,与 其他 UI-related WPF)。
- 我还发现暴露了相同的数据 via the
IMetadataInfo.GetMetaPath()
method(returns 形式为 "LM/WEBROOT/AppHost/{SiteId}"
的字符串)。
- 那么应用程序如何获得
IWpfApplicationInfoUtil
接口引用呢?
IWorkerProcessFramework->GetWpfInterface(WPF_APPLICATION_INFO_UTIL_ID)->GetApplicationPropertiesFromAppId
- 那么如何获得
IWorkerProcessFramework
呢?
- It's passed as a parameter into your
w3wp.exe
worker DLL.
- 那么让我们看看
AspNetCoreModuleV2
做了什么...
- Actually
AspNetCoreModuleV2
uses IIS's IHttpApplication
, derp。
IHttpApplication
exposes GetAppConfigPath()
which also returns a string 形式 /LM/W3SVC/1/ROOT/{Site Name}
.
- ASP.NET Core seems to use it in a few places.
- 在这一点上我放弃了,因为它现在是 6:20am,但那是一次有趣的潜水!
我正在尝试获取我在 IIS 中托管的 ASP.NET 6 应用程序的名称。我需要的正是这个带有适当大小写的名称:
在 .NET Framework 4.8 中,此名称由 HttpRequest.ApplicationPath 提供,返回时带有正确的大小写(如在 IIS 中配置的那样,而不是在即将到来的请求的 URL 中)。但是,它在 .NET 6 中不存在。
我试过了:
HttpContext.Request.PathBase
,但它 returns 与请求 URL 中的路径完全相同,而不是 IIS 中的路径- 正在注入
IServerAddressesFeature
和IWebHostEnvironment
,但其中 none 包含来自 IIS 且大小写正确的名称 IServerAddressesFeature
,但也没有在此处找到任何相关内容- 获取服务器变量:
IServerVariablesFeature serverVars = HttpContext.Features.Get<IServerVariablesFeature>()
然后是 IIS 站点名称:string iis_version = serverVars["INSTANCE_NAME"]
(参见文档 here),但它 returns 大写字母的应用程序名称(MYSITE.WEB
)
有谁知道如何获取此网站在 IIS 中配置的名称(使用正确的大小写)?
长话短说:
- 使用
APPL_MD_PATH
server-variable。- 这包含 IIS 配置数据库应用程序路径字符串。 (据我所知,“MD”代表“Meta-database”)。
- 引用文档:
https://docs.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms524602(v=vs.90)?redirectedfrom=MSDN
"
APPL_MD_PATH
- Retrieves the metabase path of the application."
像这样:
// This code assumes HttpContext is available, such as in a Middleware method or `Controller` subclass.
using Microsoft.AspNetCore.Http;
String? iisMetabasePath = httpContext.GetServerVariable("APPL_MD_PATH");
// or (long-form):
String? iisMetabasePath = HttpContextServerVariableExtensions.GetServerVariable( httpContext, "APPL_MD_PATH" );
然后 trim-off /LM/W3SVC/
部分。
请注意,当您 运行 您的代码在 IIS 之外时,例如使用 ASP.NET Core 的开发服务器,所有 IIS-specific 数据,例如 "APPL_MD_PATH"
都不会可用,因此请确保您也在处理这种情况。
原始研究:ApplicationRoot
发生了什么事?
是时候 bust-out ILSpy 了...
HttpRequest.ApplicationPath
是HttpRuntime.AppDomainAppVirtualPath
.HttpRuntime.AppDomainAppVirtualPath
是VirtualPath.GetVirtualPathStringNoTrailingSlash(HttpRuntime._theRuntime._appDomainAppVPath)
.HttpRuntime._theRuntime._appDomainAppVPath
设置在HttpRuntime.Init()
.HttpRuntime.Init()
从HttpRuntime.GetAppDomainString(".appVPath"))
设置_appDomainAppVPath
。- “AppDomain 字符串”很小 可序列化 标量 values that are associated with each
AppDomain
. - 一般来说,.NET Framework 中的 ASP.NET(又名
System.Web
)会为 IIS 中的每个 Application Scope 创建一个新的AppDomain
。 - 当然还有 AppDomains no-longer exist in .NET Core and later。
- 所以让我们找出
".appVPath"
的String
值从何而来...
- “AppDomain 字符串”很小 可序列化 标量 values that are associated with each
System.Web.Hosting.ApplicationManager::PopulateDomainBindings
集dict.Add(".appVPath", appVPath.VirtualPathString)
- “域绑定”在此上下文中指的是 AppDomain 绑定:与 DNS domain-names 或
Host
header 完全无关IIS 中的绑定。是的,超载的术语。
- “域绑定”在此上下文中指的是 AppDomain 绑定:与 DNS domain-names 或
PopulateDomainBindings
被System.Web.Hosting.ApplicationManager::CreateAppDomainWithHostingEnvironment
调用。- 它得到
virtualPath: VirtualPath.Create(appHost.GetVirtualPath())
。
- 它得到
appHost.GetVirtualPath()
是IApplicationHost.GetVirtualPath()
。- 有 2 个 in-box 实现:
System.Web.Hosting.ISAPIApplicationHost
和System.Web.Hosting.SimpleApplicationHost
。我们对ISAPIApplicationHost
. 感兴趣
- 有 2 个 in-box 实现:
ISAPIApplicationHost
从IAppManagerAppDomainFactory.Create
方法中String appId
和String appPath
的 运行time 参数获取其 virtualPath。- 而
IAppManagerAppDomainFactory
是IIS直接使用的COM接口。- 剧情变厚了...
- 而
- 此时我迷路了 through the legacy IIS 6 ISAPI documentation,寻找
IAppManagerAppDomainFactory
的原始 COM 定义的踪迹,但找到了 empty-handed。- 它可能由
webengine4.dll
处理,它是一个本机 DLL,我现在没有时间 bust-out Ghidra... - 我确实注意到 ISAPI 请求 entrypoint method
HttpExtensionProc
(and itsLPEXTENSION_CONTROL_BLOCK
parameter) 不 包含 IIS 应用程序范围AppId
或虚拟路径,它让我感到惊讶 - 但最重要的是:这表明该值可能来自GetServerVariable
或ServerSupportFunction
回调.... - 然而,这可能是浪费时间 IIS 6 是 不是 IIS7+ 并且 IIS7+ 的接口 no-longer 称为“ISAPI”,但仅称为“IIS Native-Code API”(这是我最近看到的最平淡无奇的API名字了...)。
- 它可能由
- 因此,从 “IIS Native-Code API” 文档 I quickly found the
IWpfApplicationInfoUtil::GetApplicationPropertiesFromAppId
method (here "WPF" means "Worker Process Framework”开始,与 其他 UI-related WPF)。- 我还发现暴露了相同的数据 via the
IMetadataInfo.GetMetaPath()
method(returns 形式为"LM/WEBROOT/AppHost/{SiteId}"
的字符串)。 - 那么应用程序如何获得
IWpfApplicationInfoUtil
接口引用呢?IWorkerProcessFramework->GetWpfInterface(WPF_APPLICATION_INFO_UTIL_ID)->GetApplicationPropertiesFromAppId
- 那么如何获得
IWorkerProcessFramework
呢?- It's passed as a parameter into your
w3wp.exe
worker DLL. - 那么让我们看看
AspNetCoreModuleV2
做了什么...
- It's passed as a parameter into your
- 那么如何获得
- 我还发现暴露了相同的数据 via the
- Actually
AspNetCoreModuleV2
uses IIS'sIHttpApplication
, derp。IHttpApplication
exposesGetAppConfigPath()
which also returns a string 形式/LM/W3SVC/1/ROOT/{Site Name}
.- ASP.NET Core seems to use it in a few places.
- 在这一点上我放弃了,因为它现在是 6:20am,但那是一次有趣的潜水!