diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj index 85cb5b49021d..8e1eb1f7c700 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj @@ -35,6 +35,7 @@ + @@ -49,6 +50,7 @@ + diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ModuleEnvironment.cpp b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ModuleEnvironment.cpp new file mode 100644 index 000000000000..7b333bdda889 --- /dev/null +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ModuleEnvironment.cpp @@ -0,0 +1,58 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +#include "ModuleEnvironment.h" +#include +#include + +// Set in the RegisterModule call IIS uses to initiate the module +extern DWORD g_dwIISServerVersion; + +static std::wstring GetIISVersion() { + int major = (int)(g_dwIISServerVersion >> 16); + int minor = (int)(g_dwIISServerVersion & 0xffff); + + std::wstringstream version; + version << major << "." << minor; + + return version.str(); +} + +static std::wstring ToVirtualPath(const std::wstring& configurationPath) { + int segments = 0; + size_t position = configurationPath.find('/'); + + // Skip first 4 segments of config path + while (segments != 3 && position != std::wstring::npos) + { + segments++; + position = configurationPath.find('/', position + 1); + } + + if (position != std::wstring::npos) + { + return configurationPath.substr(position); + } + + return L"/"; +} + +void SetApplicationEnvironmentVariables(_In_ IHttpServer &server, _In_ IHttpContext &pHttpContext) { + SetEnvironmentVariable(L"ASPNETCORE_IIS_VERSION", GetIISVersion().c_str()); + + SetEnvironmentVariable(L"ASPNETCORE_IIS_APP_POOL_ID", server.GetAppPoolName()); + + IHttpServer2* server2; + if (SUCCEEDED(HttpGetExtendedInterface(&server, &server, &server2))) { + SetEnvironmentVariable(L"ASPNETCORE_IIS_APP_POOL_CONFIG_FILE", server2->GetAppPoolConfigFile()); + } + + IHttpSite* site = pHttpContext.GetSite(); + SetEnvironmentVariable(L"ASPNETCORE_IIS_SITE_NAME", site->GetSiteName()); + SetEnvironmentVariable(L"ASPNETCORE_IIS_SITE_ID", std::to_wstring(site->GetSiteId()).c_str()); + + IHttpApplication* app = pHttpContext.GetApplication(); + SetEnvironmentVariable(L"ASPNETCORE_IIS_APP_CONFIG_PATH", app->GetAppConfigPath()); + SetEnvironmentVariable(L"ASPNETCORE_IIS_APPLICATION_ID", app->GetApplicationId()); + SetEnvironmentVariable(L"ASPNETCORE_IIS_APPLICATION_VIRTUAL_PATH", ToVirtualPath(app->GetAppConfigPath()).c_str()); +} diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ModuleEnvironment.h b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ModuleEnvironment.h new file mode 100644 index 000000000000..449ef41688bf --- /dev/null +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/ModuleEnvironment.h @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +#pragma once + +void SetApplicationEnvironmentVariables(_In_ IHttpServer& server, _In_ IHttpContext& pHttpContext); diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp index cecd62a3262e..519a36da628e 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp @@ -16,6 +16,7 @@ #include "ConfigurationLoadException.h" #include "resource.h" #include "file_utility.h" +#include "ModuleEnvironment.h" extern HINSTANCE g_hServerModule; extern BOOL g_fInAppOfflineShutdown; @@ -72,6 +73,8 @@ APPLICATION_INFO::CreateHandler( HRESULT APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext) { + SetApplicationEnvironmentVariables(m_pServer, pHttpContext); + auto& pHttpApplication = *pHttpContext.GetApplication(); if (AppOfflineApplication::ShouldBeStarted(pHttpApplication)) { diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/dllmain.cpp b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/dllmain.cpp index acf90e07c622..1fde8723bd77 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/dllmain.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/dllmain.cpp @@ -19,6 +19,7 @@ BOOL g_fRecycleProcessCalled = FALSE; BOOL g_fInShutdown = FALSE; BOOL g_fInAppOfflineShutdown = FALSE; HINSTANCE g_hServerModule; +DWORD g_dwIISServerVersion; VOID StaticCleanup() @@ -90,7 +91,7 @@ HRESULT --*/ { - UNREFERENCED_PARAMETER(dwServerVersion); + g_dwIISServerVersion = dwServerVersion; if (pHttpServer->IsCommandLineLaunch()) { diff --git a/src/Servers/IIS/IIS/samples/NativeIISSample/Startup.cs b/src/Servers/IIS/IIS/samples/NativeIISSample/Startup.cs index cf3267fff681..0ff3b86369c6 100644 --- a/src/Servers/IIS/IIS/samples/NativeIISSample/Startup.cs +++ b/src/Servers/IIS/IIS/samples/NativeIISSample/Startup.cs @@ -96,11 +96,32 @@ public void Configure(IApplicationBuilder app) } await context.Response.WriteAsync(Environment.NewLine); - var addresses = context.RequestServices.GetService().Features.Get(); + var server = context.RequestServices.GetService(); + + var addresses = server.Features.Get(); foreach (var key in addresses.Addresses) { await context.Response.WriteAsync(key + Environment.NewLine); } + + if (server.Features.Get() is { } envFeature) + { + await context.Response.WriteAsync(Environment.NewLine); + await context.Response.WriteAsync("IIS Environment Information:" + Environment.NewLine); + await context.Response.WriteAsync("IIS Version: " + envFeature.IISVersion + Environment.NewLine); + await context.Response.WriteAsync("ApplicationId: " + envFeature.ApplicationId + Environment.NewLine); + await context.Response.WriteAsync("Application Path: " + envFeature.ApplicationPhysicalPath + Environment.NewLine); + await context.Response.WriteAsync("Application Virtual Path: " + envFeature.ApplicationVirtualPath + Environment.NewLine); + await context.Response.WriteAsync("Application Config Path: " + envFeature.AppConfigPath + Environment.NewLine); + await context.Response.WriteAsync("AppPool ID: " + envFeature.AppPoolId + Environment.NewLine); + await context.Response.WriteAsync("AppPool Config File: " + envFeature.AppPoolConfigFile + Environment.NewLine); + await context.Response.WriteAsync("Site ID: " + envFeature.SiteId + Environment.NewLine); + await context.Response.WriteAsync("Site Name: " + envFeature.SiteName + Environment.NewLine); + } + else + { + await context.Response.WriteAsync($"No {nameof(IIISEnvironmentFeature)} available." + Environment.NewLine); + } }); } diff --git a/src/Servers/IIS/IIS/src/Core/IISEnvironmentFeature.cs b/src/Servers/IIS/IIS/src/Core/IISEnvironmentFeature.cs new file mode 100644 index 000000000000..703ce1825489 --- /dev/null +++ b/src/Servers/IIS/IIS/src/Core/IISEnvironmentFeature.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.AspNetCore.Server.IIS.Core; + +internal sealed class IISEnvironmentFeature : IIISEnvironmentFeature +{ + public static bool TryCreate(IConfiguration configuration, [NotNullWhen(true)] out IIISEnvironmentFeature? result) + { + var feature = new IISEnvironmentFeature(configuration); + + if (feature.IISVersion is not null) + { + result = feature; + return true; + } + + result = null; + return false; + } + + private IISEnvironmentFeature(IConfiguration configuration) + { + if (Version.TryParse(configuration["IIS_VERSION"], out var version)) + { + IISVersion = version; + } + + if (uint.TryParse(configuration["IIS_SITE_ID"], out var siteId)) + { + SiteId = siteId; + } + + AppPoolId = configuration["IIS_APP_POOL_ID"] ?? string.Empty; + AppPoolConfigFile = configuration["IIS_APP_POOL_CONFIG_FILE"] ?? string.Empty; + AppConfigPath = configuration["IIS_APP_CONFIG_PATH"] ?? string.Empty; + ApplicationPhysicalPath = configuration["IIS_PHYSICAL_PATH"] ?? string.Empty; + ApplicationVirtualPath = configuration["IIS_APPLICATION_VIRTUAL_PATH"] ?? string.Empty; + ApplicationId = configuration["IIS_APPLICATION_ID"] ?? string.Empty; + SiteName = configuration["IIS_SITE_NAME"] ?? string.Empty; + } + + public Version IISVersion { get; } = null!; + + public string AppPoolId { get; } + + public string AppPoolConfigFile { get; } + + public string AppConfigPath { get; } + + public string ApplicationPhysicalPath { get; } + + public string ApplicationVirtualPath { get; } + + public string ApplicationId { get; } + + public string SiteName { get; } + + public uint SiteId { get; } +} diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpServer.cs b/src/Servers/IIS/IIS/src/Core/IISHttpServer.cs index 44fff105615d..3390478626a5 100644 --- a/src/Servers/IIS/IIS/src/Core/IISHttpServer.cs +++ b/src/Servers/IIS/IIS/src/Core/IISHttpServer.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -58,6 +59,7 @@ public IISHttpServer( IISNativeApplication nativeApplication, IHostApplicationLifetime applicationLifetime, IAuthenticationSchemeProvider authentication, + IConfiguration configuration, IOptions options, ILogger logger ) @@ -77,6 +79,11 @@ ILogger logger Features.Set(_serverAddressesFeature); + if (IISEnvironmentFeature.TryCreate(configuration, out var iisEnvFeature)) + { + Features.Set(iisEnvFeature); + } + if (_options.MaxRequestBodySize > _options.IisMaxRequestSizeLimit) { _logger.LogWarning(CoreStrings.MaxRequestLimitWarning); diff --git a/src/Servers/IIS/IIS/src/IIISEnvironmentFeature.cs b/src/Servers/IIS/IIS/src/IIISEnvironmentFeature.cs new file mode 100644 index 000000000000..3ff93153c971 --- /dev/null +++ b/src/Servers/IIS/IIS/src/IIISEnvironmentFeature.cs @@ -0,0 +1,55 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.AspNetCore.Server.IIS; + +/// +/// This feature provides access to IIS application information +/// +public interface IIISEnvironmentFeature +{ + /// + /// Gets the version of IIS that is being used. + /// + Version IISVersion { get; } + + /// + /// Gets the AppPool name that is currently running + /// + string AppPoolId { get; } + + /// + /// Gets the path to the AppPool config + /// + string AppPoolConfigFile { get; } + + /// + /// Gets path to the application configuration that is currently running + /// + string AppConfigPath { get; } + + /// + /// Gets the physical path of the application. + /// + string ApplicationPhysicalPath { get; } + + /// + /// Gets the virtual path of the application. + /// + string ApplicationVirtualPath { get; } + + /// + /// Gets ID of the current application. + /// + string ApplicationId { get; } + + /// + /// Gets the name of the current site. + /// + string SiteName { get; } + + /// + /// Gets the id of the current site. + /// + uint SiteId { get; } +} diff --git a/src/Servers/IIS/IIS/src/PublicAPI.Unshipped.txt b/src/Servers/IIS/IIS/src/PublicAPI.Unshipped.txt index bdbf94be0126..76ef88049f41 100644 --- a/src/Servers/IIS/IIS/src/PublicAPI.Unshipped.txt +++ b/src/Servers/IIS/IIS/src/PublicAPI.Unshipped.txt @@ -26,4 +26,14 @@ *REMOVED*override Microsoft.AspNetCore.Server.IIS.Core.WriteOnlyStream.ReadTimeout.get -> int *REMOVED*override Microsoft.AspNetCore.Server.IIS.Core.WriteOnlyStream.ReadTimeout.set -> void *REMOVED*override Microsoft.AspNetCore.Server.IIS.Core.WriteOnlyStream.Seek(long offset, System.IO.SeekOrigin origin) -> long -*REMOVED*override Microsoft.AspNetCore.Server.IIS.Core.WriteOnlyStream.SetLength(long value) -> void \ No newline at end of file +*REMOVED*override Microsoft.AspNetCore.Server.IIS.Core.WriteOnlyStream.SetLength(long value) -> void +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature.AppConfigPath.get -> string! +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature.ApplicationId.get -> string! +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature.ApplicationPhysicalPath.get -> string! +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature.ApplicationVirtualPath.get -> string! +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature.AppPoolConfigFile.get -> string! +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature.AppPoolId.get -> string! +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature.IISVersion.get -> System.Version! +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature.SiteId.get -> uint +Microsoft.AspNetCore.Server.IIS.IIISEnvironmentFeature.SiteName.get -> string! diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/RequestResponseTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/RequestResponseTests.cs index b56e6c734e83..f919d911891b 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/RequestResponseTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/RequestResponseTests.cs @@ -611,6 +611,28 @@ public async Task HostingEnvironmentIsCorrect() Assert.Equal(_fixture.DeploymentResult.ContentRoot + "\\", await _fixture.Client.GetStringAsync("/ASPNETCORE_IIS_PHYSICAL_PATH")); } + [ConditionalTheory] + [InlineData("IIISEnvironmentFeature")] + [InlineData("IIISEnvironmentFeatureConfig")] + public async Task IISEnvironmentFeatureIsAvailable(string endpoint) + { + var siteName = _fixture.DeploymentResult.DeploymentParameters.SiteName.ToUpperInvariant(); + + var expected = $""" + IIS Version: 10.0 + ApplicationId: /LM/W3SVC/1/ROOT + Application Path: {_fixture.DeploymentResult.ContentRoot}\ + Application Virtual Path: / + Application Config Path: MACHINE/WEBROOT/APPHOST/{siteName} + AppPool ID: {_fixture.DeploymentResult.AppPoolName} + AppPool Config File: {_fixture.DeploymentResult.DeploymentParameters.ServerConfigLocation} + Site ID: 1 + Site Name: {siteName} + """; + + Assert.Equal(expected, await _fixture.Client.GetStringAsync($"/{endpoint}")); + } + [ConditionalTheory] [InlineData(65000)] [InlineData(1000000)] diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs index 90e154eeb95f..fba1940f881e 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs @@ -67,6 +67,38 @@ public void ConfigureServices(IServiceCollection serviceCollection) private async Task BaseDirectory(HttpContext ctx) => await ctx.Response.WriteAsync(AppContext.BaseDirectory); + private async Task IIISEnvironmentFeatureConfig(HttpContext ctx) + { + var config = ctx.RequestServices.GetService(); + + await ctx.Response.WriteAsync("IIS Version: " + config["IIS_VERSION"] + Environment.NewLine); + await ctx.Response.WriteAsync("ApplicationId: " + config["IIS_APPLICATION_ID"] + Environment.NewLine); + await ctx.Response.WriteAsync("Application Path: " + config["IIS_PHYSICAL_PATH"] + Environment.NewLine); + await ctx.Response.WriteAsync("Application Virtual Path: " + config["IIS_APPLICATION_VIRTUAL_PATH"] + Environment.NewLine); + await ctx.Response.WriteAsync("Application Config Path: " + config["IIS_APP_CONFIG_PATH"] + Environment.NewLine); + await ctx.Response.WriteAsync("AppPool ID: " + config["IIS_APP_POOL_ID"] + Environment.NewLine); + await ctx.Response.WriteAsync("AppPool Config File: " + config["IIS_APP_POOL_CONFIG_FILE"] + Environment.NewLine); + await ctx.Response.WriteAsync("Site ID: " + config["IIS_SITE_ID"] + Environment.NewLine); + await ctx.Response.WriteAsync("Site Name: " + config["IIS_SITE_NAME"]); + } + +#if !FORWARDCOMPAT + private async Task IIISEnvironmentFeature(HttpContext ctx) + { + var envFeature = ctx.RequestServices.GetService().Features.Get(); + + await ctx.Response.WriteAsync("IIS Version: " + envFeature.IISVersion + Environment.NewLine); + await ctx.Response.WriteAsync("ApplicationId: " + envFeature.ApplicationId + Environment.NewLine); + await ctx.Response.WriteAsync("Application Path: " + envFeature.ApplicationPhysicalPath + Environment.NewLine); + await ctx.Response.WriteAsync("Application Virtual Path: " + envFeature.ApplicationVirtualPath + Environment.NewLine); + await ctx.Response.WriteAsync("Application Config Path: " + envFeature.AppConfigPath + Environment.NewLine); + await ctx.Response.WriteAsync("AppPool ID: " + envFeature.AppPoolId + Environment.NewLine); + await ctx.Response.WriteAsync("AppPool Config File: " + envFeature.AppPoolConfigFile + Environment.NewLine); + await ctx.Response.WriteAsync("Site ID: " + envFeature.SiteId + Environment.NewLine); + await ctx.Response.WriteAsync("Site Name: " + envFeature.SiteName); + } +#endif + private async Task ASPNETCORE_IIS_PHYSICAL_PATH(HttpContext ctx) => await ctx.Response.WriteAsync(Environment.GetEnvironmentVariable("ASPNETCORE_IIS_PHYSICAL_PATH")); private async Task ServerAddresses(HttpContext ctx) @@ -1128,7 +1160,7 @@ private async Task TransferEncodingHeadersWithMultipleValues(HttpContext ctx) try { #if !FORWARDCOMPAT - Assert.True(ctx.Request.CanHaveBody()); + Assert.True(ctx.Request.CanHaveBody()); #endif Assert.True(ctx.Request.Headers.ContainsKey("Transfer-Encoding")); Assert.Equal("gzip, chunked", ctx.Request.Headers["Transfer-Encoding"]); @@ -1146,7 +1178,7 @@ private async Task TransferEncodingAndContentLengthShouldBeRemove(HttpContext ct try { #if !FORWARDCOMPAT - Assert.True(ctx.Request.CanHaveBody()); + Assert.True(ctx.Request.CanHaveBody()); #endif Assert.True(ctx.Request.Headers.ContainsKey("Transfer-Encoding")); Assert.Equal("gzip, chunked", ctx.Request.Headers["Transfer-Encoding"]); diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs index 509f81db631c..20a4de0ca368 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs @@ -28,6 +28,7 @@ public class IISDeployer : IISDeployerBase private string _configPath; private string _applicationHostConfig; private string _debugLogFile; + private string _appPoolName; private bool _disposed; public Process HostProcess { get; set; } @@ -109,6 +110,8 @@ public override Task DeployAsync() var uri = TestUriHelper.BuildTestUri(ServerType.IIS, DeploymentParameters.ApplicationBaseUriHint); StartIIS(uri, contentRoot); + IISDeploymentParameters.ServerConfigLocation = Path.Combine(@"C:\inetpub\temp\apppools", _appPoolName, $"{_appPoolName}.config"); + // Warm up time for IIS setup. Logger.LogInformation("Successfully finished IIS application directory setup."); return Task.FromResult(new IISDeploymentResult( @@ -117,7 +120,8 @@ public override Task DeployAsync() applicationBaseUri: uri.ToString(), contentRoot: contentRoot, hostShutdownToken: _hostShutdownToken.Token, - hostProcess: HostProcess + hostProcess: HostProcess, + appPoolName: _appPoolName )); } } @@ -239,6 +243,8 @@ private void WaitUntilSiteStarted(string contentRoot) RetryServerManagerAction(serverManager => { var site = FindSite(serverManager, contentRoot); + IISDeploymentParameters.SiteName = site.Name; + if (site == null) { PreserveConfigFiles("nositetostart"); @@ -246,6 +252,7 @@ private void WaitUntilSiteStarted(string contentRoot) } var appPool = serverManager.ApplicationPools.Single(); + _appPoolName = appPool.Name; if (appPool.State != ObjectState.Started && appPool.State != ObjectState.Starting) { var state = appPool.Start(); @@ -500,7 +507,7 @@ private void RetryServerManagerAction(Action action) private void PreserveConfigFiles(string fileNamePrefix) { - HelixHelper.PreserveFile(Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"), fileNamePrefix+".web.config"); + HelixHelper.PreserveFile(Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "web.config"), fileNamePrefix + ".web.config"); HelixHelper.PreserveFile(Path.Combine(_configPath, "applicationHost.config"), fileNamePrefix + ".applicationHost.config"); HelixHelper.PreserveFile(Path.Combine(Environment.SystemDirectory, @"inetsrv\config\ApplicationHost.config"), fileNamePrefix + ".inetsrv.applicationHost.config"); HelixHelper.PreserveFile(Path.Combine(Environment.SystemDirectory, @"inetsrv\config\redirection.config"), fileNamePrefix + ".inetsrv.redirection.config"); diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentResult.cs b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentResult.cs index 043852daa874..1cf6072b547d 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentResult.cs +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentResult.cs @@ -10,12 +10,16 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS; public class IISDeploymentResult : DeploymentResult { public ILogger Logger { get; set; } + public Process HostProcess { get; } + public string AppPoolName { get; } + public IISDeploymentResult(ILoggerFactory loggerFactory, IISDeploymentParameters deploymentParameters, string applicationBaseUri, string contentRoot, + string appPoolName, CancellationToken hostShutdownToken, Process hostProcess) : base(loggerFactory, @@ -24,6 +28,7 @@ public IISDeploymentResult(ILoggerFactory loggerFactory, contentRoot, hostShutdownToken) { + AppPoolName = appPoolName; HostProcess = hostProcess; Logger = loggerFactory.CreateLogger(deploymentParameters.SiteName); HttpClient = CreateClient(new HttpClientHandler()); diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs b/src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs index 951491335c54..edfdee36baa4 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs @@ -105,6 +105,7 @@ public override async Task DeployAsync() applicationBaseUri: actualUri.ToString(), contentRoot: contentRoot, hostShutdownToken: hostExitToken, + appPoolName: "IISExpressAppPool", hostProcess: _hostProcess); } }