116 lines
4.1 KiB
C#
116 lines
4.1 KiB
C#
// 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.
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.AspNet.Server.Testing.Common;
|
|
|
|
namespace Microsoft.AspNet.Server.Testing
|
|
{
|
|
/// <summary>
|
|
/// Deployer for WebListener and Kestrel.
|
|
/// </summary>
|
|
public class SelfHostDeployer : ApplicationDeployer
|
|
{
|
|
private Process _hostProcess;
|
|
|
|
public SelfHostDeployer(DeploymentParameters deploymentParameters, ILogger logger)
|
|
: base(deploymentParameters, logger)
|
|
{
|
|
}
|
|
|
|
public override DeploymentResult Deploy()
|
|
{
|
|
// Start timer
|
|
StartTimer();
|
|
|
|
PickRuntime();
|
|
|
|
if (DeploymentParameters.PublishApplicationBeforeDeployment)
|
|
{
|
|
DnuPublish();
|
|
}
|
|
|
|
var uri = TestUriHelper.BuildTestUri(DeploymentParameters.ApplicationBaseUriHint);
|
|
// Launch the host process.
|
|
var hostExitToken = StartSelfHost(uri);
|
|
|
|
return new DeploymentResult
|
|
{
|
|
WebRootLocation = DeploymentParameters.ApplicationPath,
|
|
DeploymentParameters = DeploymentParameters,
|
|
ApplicationBaseUri = uri.ToString(),
|
|
HostShutdownToken = hostExitToken
|
|
};
|
|
}
|
|
|
|
private CancellationToken StartSelfHost(Uri uri)
|
|
{
|
|
var commandName = DeploymentParameters.Command;
|
|
if (string.IsNullOrEmpty(commandName))
|
|
{
|
|
commandName = "run";
|
|
}
|
|
|
|
var dnxPath = Path.Combine(TargetRuntimeBinPath, DnxCommandName);
|
|
var dnxArgs = $"-p \"{DeploymentParameters.ApplicationPath}\" {commandName} " +
|
|
$"--server.urls {uri} " +
|
|
$"--server {(DeploymentParameters.ServerType == ServerType.WebListener ? "Microsoft.AspNet.Server.WebListener" : "Microsoft.AspNet.Server.Kestrel")}";
|
|
|
|
Logger.LogInformation($"Executing {dnxPath} {dnxArgs}");
|
|
|
|
var startInfo = new ProcessStartInfo
|
|
{
|
|
FileName = dnxPath,
|
|
Arguments = dnxArgs,
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true,
|
|
RedirectStandardError = true,
|
|
RedirectStandardOutput = true,
|
|
// Trying a work around for https://github.com/aspnet/Hosting/issues/140.
|
|
RedirectStandardInput = true
|
|
};
|
|
|
|
AddEnvironmentVariablesToProcess(startInfo);
|
|
|
|
_hostProcess = new Process() { StartInfo = startInfo };
|
|
_hostProcess.ErrorDataReceived += (sender, dataArgs) => { Logger.LogError(dataArgs.Data ?? string.Empty); };
|
|
_hostProcess.OutputDataReceived += (sender, dataArgs) => { Logger.LogInformation(dataArgs.Data ?? string.Empty); };
|
|
_hostProcess.EnableRaisingEvents = true;
|
|
var hostExitTokenSource = new CancellationTokenSource();
|
|
_hostProcess.Exited += (sender, e) =>
|
|
{
|
|
TriggerHostShutdown(hostExitTokenSource);
|
|
};
|
|
_hostProcess.Start();
|
|
_hostProcess.BeginErrorReadLine();
|
|
_hostProcess.BeginOutputReadLine();
|
|
|
|
if (_hostProcess.HasExited)
|
|
{
|
|
Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, _hostProcess.ExitCode);
|
|
throw new Exception("Failed to start host");
|
|
}
|
|
|
|
Logger.LogInformation("Started {fileName}. Process Id : {processId}", startInfo.FileName, _hostProcess.Id);
|
|
return hostExitTokenSource.Token;
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
ShutDownIfAnyHostProcess(_hostProcess);
|
|
|
|
if (DeploymentParameters.PublishApplicationBeforeDeployment)
|
|
{
|
|
CleanPublishedOutput();
|
|
}
|
|
|
|
InvokeUserApplicationCleanup();
|
|
|
|
StopTimer();
|
|
}
|
|
}
|
|
} |