Fix Console invalid handle issues. (#1029)
This commit is contained in:
parent
b359d6bed1
commit
c657e31b94
|
|
@ -277,10 +277,7 @@ IN_PROCESS_APPLICATION::LoadManagedApplication
|
||||||
goto Finished;
|
goto Finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr = m_pLoggerProvider->Start()))
|
LOG_IF_FAILED(m_pLoggerProvider->Start());
|
||||||
{
|
|
||||||
goto Finished;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_status != APPLICATION_STATUS::STARTING)
|
if (m_status != APPLICATION_STATUS::STARTING)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ register_callbacks(
|
||||||
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
|
_In_ PFN_SHUTDOWN_HANDLER shutdown_handler,
|
||||||
_In_ PFN_ASYNC_COMPLETION_HANDLER async_completion_handler,
|
_In_ PFN_ASYNC_COMPLETION_HANDLER async_completion_handler,
|
||||||
_In_ VOID* pvRequstHandlerContext,
|
_In_ VOID* pvRequstHandlerContext,
|
||||||
_In_ VOID* pvShutdownHandlerContext
|
_In_ VOID* pvShutdownHandlerContext,
|
||||||
|
_Out_ BOOL* pfResetStandardStreams
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (pInProcessApplication == NULL)
|
if (pInProcessApplication == NULL)
|
||||||
|
|
@ -30,6 +31,7 @@ register_callbacks(
|
||||||
pvRequstHandlerContext,
|
pvRequstHandlerContext,
|
||||||
pvShutdownHandlerContext
|
pvShutdownHandlerContext
|
||||||
);
|
);
|
||||||
|
*pfResetStandardStreams = !pInProcessApplication->QueryConfig()->QueryStdoutLogEnabled();
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
FileOutputManager::FileOutputManager() :
|
FileOutputManager::FileOutputManager() :
|
||||||
m_hLogFileHandle(INVALID_HANDLE_VALUE),
|
m_hLogFileHandle(INVALID_HANDLE_VALUE),
|
||||||
m_fdPreviousStdOut(0),
|
m_fdPreviousStdOut(-1),
|
||||||
m_fdPreviousStdErr(0)
|
m_fdPreviousStdErr(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,14 +40,14 @@ FileOutputManager::~FileOutputManager()
|
||||||
|
|
||||||
if (m_fdPreviousStdOut >= 0)
|
if (m_fdPreviousStdOut >= 0)
|
||||||
{
|
{
|
||||||
_dup2(m_fdPreviousStdOut, _fileno(stdout));
|
LOG_LAST_ERROR_IF(SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)_get_osfhandle(m_fdPreviousStdOut)));
|
||||||
LOG_INFOF("Restoring original stdout of stdout: %d", m_fdPreviousStdOut);
|
LOG_INFOF("Restoring original stdout: %d", m_fdPreviousStdOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_fdPreviousStdErr >= 0)
|
if (m_fdPreviousStdErr >= 0)
|
||||||
{
|
{
|
||||||
_dup2(m_fdPreviousStdErr, _fileno(stderr));
|
LOG_LAST_ERROR_IF(SetStdHandle(STD_ERROR_HANDLE, (HANDLE)_get_osfhandle(m_fdPreviousStdErr)));
|
||||||
LOG_INFOF("Restoring original stdout of stdout: %d", m_fdPreviousStdOut);
|
LOG_INFOF("Restoring original stderr: %d", m_fdPreviousStdOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,10 +60,6 @@ FileOutputManager::Initialize(PCWSTR pwzStdOutLogFileName, PCWSTR pwzApplication
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileOutputManager::NotifyStartupComplete()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileOutputManager::GetStdOutContent(STRA* struStdOutput)
|
bool FileOutputManager::GetStdOutContent(STRA* struStdOutput)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public:
|
||||||
|
|
||||||
virtual bool GetStdOutContent(STRA* struStdOutput) override;
|
virtual bool GetStdOutContent(STRA* struStdOutput) override;
|
||||||
virtual HRESULT Start() override;
|
virtual HRESULT Start() override;
|
||||||
virtual void NotifyStartupComplete() override;
|
virtual void NotifyStartupComplete() override {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HandleWrapper<InvalidHandleTraits> m_hLogFileHandle;
|
HandleWrapper<InvalidHandleTraits> m_hLogFileHandle;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,9 @@ PipeOutputManager::PipeOutputManager() :
|
||||||
m_hErrReadPipe(INVALID_HANDLE_VALUE),
|
m_hErrReadPipe(INVALID_HANDLE_VALUE),
|
||||||
m_hErrWritePipe(INVALID_HANDLE_VALUE),
|
m_hErrWritePipe(INVALID_HANDLE_VALUE),
|
||||||
m_hErrThread(NULL),
|
m_hErrThread(NULL),
|
||||||
m_fDisposed(FALSE)
|
m_fDisposed(FALSE),
|
||||||
|
m_fdPreviousStdOut(-1),
|
||||||
|
m_fdPreviousStdErr(-1)
|
||||||
{
|
{
|
||||||
InitializeSRWLock(&m_srwLock);
|
InitializeSRWLock(&m_srwLock);
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +56,7 @@ PipeOutputManager::StopOutputRedirection()
|
||||||
|
|
||||||
if (m_fdPreviousStdOut >= 0)
|
if (m_fdPreviousStdOut >= 0)
|
||||||
{
|
{
|
||||||
LOG_IF_DUPFAIL(_dup2(m_fdPreviousStdOut, _fileno(stdout)));
|
LOG_LAST_ERROR_IF(SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)_get_osfhandle(m_fdPreviousStdOut)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -63,7 +65,7 @@ PipeOutputManager::StopOutputRedirection()
|
||||||
|
|
||||||
if (m_fdPreviousStdErr >= 0)
|
if (m_fdPreviousStdErr >= 0)
|
||||||
{
|
{
|
||||||
LOG_IF_DUPFAIL(_dup2(m_fdPreviousStdErr, _fileno(stderr)));
|
LOG_LAST_ERROR_IF(SetStdHandle(STD_ERROR_HANDLE, (HANDLE)_get_osfhandle(m_fdPreviousStdErr)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.IIS.Core
|
namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
{
|
{
|
||||||
|
|
@ -31,7 +32,39 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
||||||
IntPtr requestContext,
|
IntPtr requestContext,
|
||||||
IntPtr shutdownContext)
|
IntPtr shutdownContext)
|
||||||
{
|
{
|
||||||
NativeMethods.HttpRegisterCallbacks(_nativeApplication, requestHandler, shutdownHandler, onAsyncCompletion, requestContext, shutdownContext);
|
NativeMethods.HttpRegisterCallbacks(
|
||||||
|
_nativeApplication,
|
||||||
|
requestHandler,
|
||||||
|
shutdownHandler,
|
||||||
|
onAsyncCompletion,
|
||||||
|
requestContext,
|
||||||
|
shutdownContext,
|
||||||
|
out var resetStandardStreams);
|
||||||
|
|
||||||
|
if (resetStandardStreams)
|
||||||
|
{
|
||||||
|
ResetStdOutHandles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ResetStdOutHandles()
|
||||||
|
{
|
||||||
|
// By using the PipeOutputRedirection, after calling RegisterCallbacks,
|
||||||
|
// stdout and stderr will be redirected to NULL. However, if something wrote
|
||||||
|
// to stdout before redirecting, (like a Console.WriteLine during startup),
|
||||||
|
// we need to call Console.Set* to pick up the modified consoles outputs.
|
||||||
|
Console.SetOut(CreateStreamWriter(Console.OpenStandardOutput()));
|
||||||
|
Console.SetError(CreateStreamWriter(Console.OpenStandardError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StreamWriter CreateStreamWriter(Stream stdStream)
|
||||||
|
{
|
||||||
|
return new StreamWriter(
|
||||||
|
stdStream,
|
||||||
|
encoding: Console.OutputEncoding,
|
||||||
|
bufferSize: 256,
|
||||||
|
leaveOpen: true)
|
||||||
|
{ AutoFlush = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,13 @@ namespace Microsoft.AspNetCore.Server.IIS
|
||||||
private static extern void http_indicate_completion(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS notificationStatus);
|
private static extern void http_indicate_completion(IntPtr pInProcessHandler, REQUEST_NOTIFICATION_STATUS notificationStatus);
|
||||||
|
|
||||||
[DllImport(AspNetCoreModuleDll)]
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
private static extern int register_callbacks(IntPtr pInProcessApplication, PFN_REQUEST_HANDLER requestCallback, PFN_SHUTDOWN_HANDLER shutdownCallback, PFN_ASYNC_COMPLETION asyncCallback, IntPtr pvRequestContext, IntPtr pvShutdownContext);
|
private static extern int register_callbacks(IntPtr pInProcessApplication,
|
||||||
|
PFN_REQUEST_HANDLER requestCallback,
|
||||||
|
PFN_SHUTDOWN_HANDLER shutdownCallback,
|
||||||
|
PFN_ASYNC_COMPLETION asyncCallback,
|
||||||
|
IntPtr pvRequestContext,
|
||||||
|
IntPtr pvShutdownContext,
|
||||||
|
out bool resetStandardStreams);
|
||||||
|
|
||||||
[DllImport(AspNetCoreModuleDll)]
|
[DllImport(AspNetCoreModuleDll)]
|
||||||
private static extern unsafe int http_write_response_bytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected);
|
private static extern unsafe int http_write_response_bytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected);
|
||||||
|
|
@ -135,9 +141,15 @@ namespace Microsoft.AspNetCore.Server.IIS
|
||||||
Validate(http_set_completion_status(pInProcessHandler, rquestNotificationStatus));
|
Validate(http_set_completion_status(pInProcessHandler, rquestNotificationStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void HttpRegisterCallbacks(IntPtr pInProcessApplication, PFN_REQUEST_HANDLER requestCallback, PFN_SHUTDOWN_HANDLER shutdownCallback, PFN_ASYNC_COMPLETION asyncCallback, IntPtr pvRequestContext, IntPtr pvShutdownContext)
|
public static void HttpRegisterCallbacks(IntPtr pInProcessApplication,
|
||||||
|
PFN_REQUEST_HANDLER requestCallback,
|
||||||
|
PFN_SHUTDOWN_HANDLER shutdownCallback,
|
||||||
|
PFN_ASYNC_COMPLETION asyncCallback,
|
||||||
|
IntPtr pvRequestContext,
|
||||||
|
IntPtr pvShutdownContext,
|
||||||
|
out bool resetStandardStreams)
|
||||||
{
|
{
|
||||||
Validate(register_callbacks(pInProcessApplication, requestCallback, shutdownCallback, asyncCallback, pvRequestContext, pvShutdownContext));
|
Validate(register_callbacks(pInProcessApplication, requestCallback, shutdownCallback, asyncCallback, pvRequestContext, pvShutdownContext, out resetStandardStreams));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe int HttpWriteResponseBytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected)
|
public static unsafe int HttpWriteResponseBytes(IntPtr pInProcessHandler, HttpApiTypes.HTTP_DATA_CHUNK* pDataChunks, int nChunks, out bool fCompletionExpected)
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
||||||
pool.ProcessModel.IdentityType = ProcessModelIdentityType.LocalSystem;
|
pool.ProcessModel.IdentityType = ProcessModelIdentityType.LocalSystem;
|
||||||
pool.ManagedRuntimeVersion = string.Empty;
|
pool.ManagedRuntimeVersion = string.Empty;
|
||||||
pool.StartMode = StartMode.AlwaysRunning;
|
pool.StartMode = StartMode.AlwaysRunning;
|
||||||
|
|
||||||
AddEnvironmentVariables(contentRoot, pool);
|
AddEnvironmentVariables(contentRoot, pool);
|
||||||
|
|
||||||
_logger.LogInformation($"Configured AppPool {AppPoolName}");
|
_logger.LogInformation($"Configured AppPool {AppPoolName}");
|
||||||
|
|
|
||||||
|
|
@ -19,55 +19,58 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
[InlineData("CheckErrLogFile")]
|
[InlineData("CheckErrLogFile")]
|
||||||
[InlineData("CheckLogFile")]
|
[InlineData("CheckLogFile")]
|
||||||
public async Task CheckStdoutLogging(string path)
|
public async Task CheckStdoutLoggingToFile(string path)
|
||||||
{
|
{
|
||||||
var deploymentParameters = Helpers.GetBaseDeploymentParameters();
|
var deploymentParameters = Helpers.GetBaseDeploymentParameters();
|
||||||
deploymentParameters.PublishApplicationBeforeDeployment = true;
|
deploymentParameters.PublishApplicationBeforeDeployment = true;
|
||||||
deploymentParameters.PreservePublishedApplicationForDebugging = true; // workaround for keeping
|
|
||||||
|
|
||||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
var pathToLogs = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogEnabled", "true");
|
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogEnabled", "true");
|
||||||
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogFile", @".\logs\stdout");
|
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogFile", Path.Combine(pathToLogs, "std"));
|
||||||
|
|
||||||
var response = await deploymentResult.RetryingHttpClient.GetAsync(path);
|
await Helpers.AssertStarts(deploymentResult, path);
|
||||||
|
|
||||||
var responseText = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
Assert.Equal("Hello World", responseText);
|
|
||||||
|
|
||||||
StopServer();
|
StopServer();
|
||||||
|
|
||||||
var folderPath = Path.Combine(deploymentResult.DeploymentResult.ContentRoot, @"logs");
|
var fileInDirectory = Directory.GetFiles(pathToLogs).Single();
|
||||||
|
|
||||||
var fileInDirectory = Directory.GetFiles(folderPath).Single();
|
var contents = File.ReadAllText(fileInDirectory);
|
||||||
Assert.NotNull(fileInDirectory);
|
|
||||||
|
|
||||||
string contents = null;
|
|
||||||
|
|
||||||
// RetryOperation doesn't support async lambdas, call synchronous ReadAllText.
|
|
||||||
RetryHelper.RetryOperation(
|
|
||||||
() => contents = File.ReadAllText(fileInDirectory),
|
|
||||||
e => Logger.LogError($"Failed to read file: {e.Message}"),
|
|
||||||
retryCount: 10,
|
|
||||||
retryDelayMilliseconds: 100);
|
|
||||||
|
|
||||||
Assert.NotNull(contents);
|
Assert.NotNull(contents);
|
||||||
Assert.Contains("TEST MESSAGE", contents);
|
Assert.Contains("TEST MESSAGE", contents);
|
||||||
|
Assert.DoesNotContain(TestSink.Writes, context => context.Message.Contains("TEST MESSAGE"));
|
||||||
|
// TODO we should check that debug logs are restored during graceful shutdown.
|
||||||
|
// The IIS Express deployer doesn't support graceful shutdown.
|
||||||
|
//Assert.Contains(TestSink.Writes, context => context.Message.Contains("Restoring original stdout: "));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
||||||
RetryHelper.RetryOperation(
|
RetryHelper.RetryOperation(
|
||||||
() => Directory.Delete(deploymentParameters.PublishedApplicationRootPath, true),
|
() => Directory.Delete(pathToLogs, true),
|
||||||
e => Logger.LogWarning($"Failed to delete directory : {e.Message}"),
|
e => Logger.LogWarning($"Failed to delete directory : {e.Message}"),
|
||||||
retryCount: 3,
|
retryCount: 3,
|
||||||
retryDelayMilliseconds: 100);
|
retryDelayMilliseconds: 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task InvalidFilePathForLogs_ServerStillRuns()
|
||||||
|
{
|
||||||
|
var deploymentParameters = Helpers.GetBaseDeploymentParameters(publish: true);
|
||||||
|
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogEnabled", "true");
|
||||||
|
Helpers.ModifyAspNetCoreSectionInWebConfig(deploymentResult, "stdoutLogFile", Path.Combine("Q:", "std"));
|
||||||
|
|
||||||
|
await Helpers.AssertStarts(deploymentResult, "HelloWorld");
|
||||||
|
}
|
||||||
|
|
||||||
[ConditionalFact]
|
[ConditionalFact]
|
||||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||||
public async Task StartupMessagesAreLoggedIntoDebugLogFile()
|
public async Task StartupMessagesAreLoggedIntoDebugLogFile()
|
||||||
|
|
@ -96,6 +99,48 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory]
|
||||||
|
[InlineData("CheckErrLogFile")]
|
||||||
|
[InlineData("CheckLogFile")]
|
||||||
|
public async Task CheckStdoutLoggingToPipe_DoesNotCrashProcess(string path)
|
||||||
|
{
|
||||||
|
var deploymentParameters = Helpers.GetBaseDeploymentParameters(publish: true);
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
await Helpers.AssertStarts(deploymentResult, path);
|
||||||
|
|
||||||
|
StopServer();
|
||||||
|
|
||||||
|
if (deploymentParameters.ServerType == ServerType.IISExpress)
|
||||||
|
{
|
||||||
|
Assert.Contains(TestSink.Writes, context => context.Message.Contains("TEST MESSAGE"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory]
|
||||||
|
[InlineData("CheckErrLogFile")]
|
||||||
|
[InlineData("CheckLogFile")]
|
||||||
|
public async Task CheckStdoutLoggingToPipeWithFirstWrite(string path)
|
||||||
|
{
|
||||||
|
var deploymentParameters = Helpers.GetBaseDeploymentParameters(publish: true);
|
||||||
|
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
var firstWriteString = path + path;
|
||||||
|
|
||||||
|
Helpers.ModifyEnvironmentVariableCollectionInWebConfig(deploymentResult, "ASPNETCORE_INPROCESS_INITIAL_WRITE", firstWriteString);
|
||||||
|
|
||||||
|
await Helpers.AssertStarts(deploymentResult, path);
|
||||||
|
|
||||||
|
StopServer();
|
||||||
|
|
||||||
|
if (deploymentParameters.ServerType == ServerType.IISExpress)
|
||||||
|
{
|
||||||
|
// We can't read stdout logs from IIS as they aren't redirected.
|
||||||
|
Assert.Contains(TestSink.Writes, context => context.Message.Contains(firstWriteString));
|
||||||
|
Assert.Contains(TestSink.Writes, context => context.Message.Contains("TEST MESSAGE"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[ConditionalFact]
|
[ConditionalFact]
|
||||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||||
public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig()
|
public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig()
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,22 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
config.Save(webConfigFile);
|
config.Save(webConfigFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ModifyEnvironmentVariableCollectionInWebConfig(IISDeploymentResult deploymentResult, string key, string value)
|
||||||
|
{
|
||||||
|
var webConfigFile = GetWebConfigFile(deploymentResult);
|
||||||
|
var config = XDocument.Load(webConfigFile);
|
||||||
|
|
||||||
|
var envVarElement = new XElement("environmentVariable");
|
||||||
|
envVarElement.SetAttributeValue("name", key);
|
||||||
|
envVarElement.SetAttributeValue("value", value);
|
||||||
|
|
||||||
|
config.Descendants("aspNetCore").Single()
|
||||||
|
.Descendants("environmentVariables").Single()
|
||||||
|
.Add(envVarElement);
|
||||||
|
|
||||||
|
config.Save(webConfigFile);
|
||||||
|
}
|
||||||
|
|
||||||
public static void ModifyHandlerSectionInWebConfig(IISDeploymentResult deploymentResult, string handlerVersionValue)
|
public static void ModifyHandlerSectionInWebConfig(IISDeploymentResult deploymentResult, string handlerVersionValue)
|
||||||
{
|
{
|
||||||
var webConfigFile = GetWebConfigFile(deploymentResult);
|
var webConfigFile = GetWebConfigFile(deploymentResult);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|
@ -10,6 +11,13 @@ namespace IISTestSite
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
var envVariable = Environment.GetEnvironmentVariable("ASPNETCORE_INPROCESS_INITIAL_WRITE");
|
||||||
|
if (!string.IsNullOrEmpty(envVariable))
|
||||||
|
{
|
||||||
|
Console.WriteLine(envVariable);
|
||||||
|
Console.Error.WriteLine(envVariable);
|
||||||
|
}
|
||||||
|
|
||||||
var host = new WebHostBuilder()
|
var host = new WebHostBuilder()
|
||||||
.ConfigureLogging((_, factory) =>
|
.ConfigureLogging((_, factory) =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -753,6 +753,5 @@ namespace IISTestSite
|
||||||
}
|
}
|
||||||
await context.Response.WriteAsync("Response End");
|
await context.Response.WriteAsync("Response End");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue