检查ASP.NET(Core)应用程序是否驻留在IIS中

puruo6ea  于 2023-08-05  发布在  .NET
关注(0)|答案(4)|浏览(156)

如何检查应用程序内部是否托管在IIS中?

mrzz3bfm

mrzz3bfm1#

检查是否设置了环境变量APP_POOL_ID。

public static bool InsideIIS() =>
    System.Environment.GetEnvironmentVariable("APP_POOL_ID") is string;

字符串
All of environment variables that iis sets on a child process

gupuwyp2

gupuwyp22#

我试过Branimir Ričko的答案,但发现它不正确:在IIS Express下运行时,也会设置此环境变量。
以下是我的修改版本:

static bool IsRunningInsideIIS() =>
    System.Environment.GetEnvironmentVariable("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES") is string startupAssemblies &&  
 startupAssemblies.Contains(typeof(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults).Namespace);

字符串

vnjpjtjt

vnjpjtjt3#

我相信没有直接的方法可以实现这一目标。至少我还没找到我可以告诉你的原因是,ASP.NET核心应用程序实际上是一个自包含的应用程序,它不知道它的父上下文,除非后者会透露有关它自己的信息。
例如,在配置文件中,我们可以告诉我们正在运行的安装类型:productiondevelopment。我们可以假设productionIIS,而development不是。但这对我不起作用。因为我的生产设置可能是IISwindows service
因此,我通过根据应用程序要执行的运行类型为应用程序提供不同的命令行参数来解决这个问题。实际上,这对我来说很自然,因为windows service确实需要不同的方法来运行。
例如,在我的案例中,代码看起来有点像这样:

namespace AspNetCore.Web.App
{
    using McMaster.Extensions.CommandLineUtils;
    using Microsoft.AspNetCore;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Hosting.WindowsServices;
    using System;
    using System.Diagnostics;
    using System.IO;

    public class Program
    {
        #region Public Methods

        public static IWebHostBuilder GetHostBuilder(string[] args, int port) =>
            WebHost.CreateDefaultBuilder(args)
                .UseKestrel()
                .UseIISIntegration()
                .UseUrls($"http://*:{port}")
                .UseStartup<Startup>();

        public static void Main(string[] args)
        {
            var app = new CommandLineApplication();

            app.HelpOption();
            var optionHosting = app.Option("--hosting <TYPE>", "Type of the hosting used. Valid options: `service` and `console`, `console` is the default one", CommandOptionType.SingleValue);
            var optionPort = app.Option("--port <NUMBER>", "Post will be used, `5000` is the default one", CommandOptionType.SingleValue);

            app.OnExecute(() =>
            {
                //
                var hosting = optionHosting.HasValue()
                    ? optionHosting.Value()
                    : "console";

                var port = optionPort.HasValue()
                    ? new Func<int>(() =>
                    {
                        if (int.TryParse(optionPort.Value(), out var number))
                        {
                            // Returning successfully parsed number
                            return number;
                        }

                        // Returning default port number in case of failure
                        return 5000;
                    })()
                    : 5000;

                var builder = GetHostBuilder(args, port);

                if (Debugger.IsAttached || hosting.ToLowerInvariant() != "service")
                {
                    builder
                        .UseContentRoot(Directory.GetCurrentDirectory())
                        .Build()
                        .Run();
                }
                else
                {
                    builder
                        .UseContentRoot(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName))
                        .Build()
                        .RunAsService();
                }
            });

            app.Execute(args);
        }

        #endregion Public Methods
    }
}

字符串
此代码不仅允许选择托管类型(serviceconsole-IIS应该使用的选项),而且还允许更改端口,这很重要,当您作为Windows服务运行时。
另一个好处是使用参数解析库McMaster.Extensions.CommandLineUtils-它将显示有关配置的命令行开关的信息,因此很容易选择正确的值。

vh0rcniy

vh0rcniy4#

无论是Branimir Ričko的答案,还是使用环境变量ASPNETCORE_HOSTINGSTARTUPASSEMBLIES的答案,还是对Branimir的答案的评论,它使用了环境变量ASPNETCORE_IIS_PHYSICAL_PATH,对我来说都不起作用。然而,这个答案https://stackoverflow.com/a/71610893/967448提供了一种方法,尽管它是脆弱的,并且可能在未来破裂。答案是使用IServer实现。但是,如果你像我一样,需要一种方法来做到这一点,只是暂时解决IIS中的bug,那么这个解决方案可能就足够好了。如果你需要我的答案,你可能应该对布拉尼米尔对他的回答的评论投赞成票。

相关问题