在运行时检查托管服务器是IIS还是Kestrel在ASPNET Core中

Cha*_*lie 7 c# iis .net-core kestrel-http-server asp.net-core

我目前在Kestrel(本地)或IIS InProcess(生产)下运行我的应用程序。

return WebHost.CreateDefaultBuilder(args)
    .ConfigureKestrel(options => options.AddServerHeader = false)
    .UseIIS()
    .UseStartup<Startup>();
Run Code Online (Sandbox Code Playgroud)

我希望能够在运行时在控制器中获取托管服务器的名称,以便实现以下目标:

if (hostingServer == "kestrel")
{
    DoSomething();
}
else
{
    DoSomethingElse();
}
Run Code Online (Sandbox Code Playgroud)

在这种特定情况下,可以避免以下事实:Kestrel的响应标头中不支持非ascii字符。理想情况下,我将删除non-ascii标头,但目前它是传统互操作性所必需的。

任何帮助将不胜感激。

Lex*_* Li 5

最简单的方法可能就是阅读System.Diagnostics.Process.GetCurrentProcess().ProcessName。如果是w3wp或者iisexpress您知道主机是 IIS/IIS Express,则 while dotnet(或使用独立部署时的其他名称)表示 Kestrel。这仅适用于进程内部署。如果你不在进程中,这将不起作用。了解更多信息https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module

例子:

/// <summary>
/// Check if this process is running on Windows in an in process instance in IIS
/// </summary>
/// <returns>True if Windows and in an in process instance on IIS, false otherwise</returns>
public static bool IsRunningInProcessIIS()
{
    if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        return false;
    }

    string processName = Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().ProcessName);
    return (processName.Contains("w3wp", StringComparison.OrdinalIgnoreCase) ||
        processName.Contains("iisexpress", StringComparison.OrdinalIgnoreCase));
}
Run Code Online (Sandbox Code Playgroud)


Son*_*Cue 5

检查进程名称对我不起作用,即使在使用 InProcess 托管在 IIS 中时,它仍然代理该dotnet进程(我的猜测是您需要获取父进程才能获取 w3wp 进程)。

.NET CoreIsAspNetCoreModuleLoaded()NativeMethods.cs 中的内部调用可以在WebHostBuilderIISExtensions.cs 中找到。因此,可以使用以下代码来检查 IIS。

internal static class NativeMethods
{
    internal const string AspNetCoreModuleDll = "aspnetcorev2_inprocess.dll";

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

    public static bool IsAspNetCoreModuleLoaded()
    {
        return GetModuleHandle(AspNetCoreModuleDll) != IntPtr.Zero;
    }
}
Run Code Online (Sandbox Code Playgroud)


Gre*_*reg 0

当应用程序启动时,托管方法可以在IApplicationBuilder.ServerFeatures. 通过这里,您可以找到引用 Kestrel 与反向代理配置的项目。

Startup.Configure 方法中可用的 IApplicationBuilder 公开 IFeatureCollection 类型的 ServerFeatures 属性。Kestrel 和 HTTP.sys 仅公开一个功能,即 IServerAddressesFeature,但不同的服务器实现可能会公开其他功能。IServerAddressesFeature 可用于找出服务器实现在运行时绑定的端口。

该属性是一个集合,因此您需要筛选与 IIS 反向代理和 Kestrel 相关的特定托管方法。