private void PublishWithDotnetExe(string framework) { var projectFile = Path.Combine(SourceApplicationsDirectoryPath, ApplicationDirectoryName, ApplicationDirectoryName + ".csproj"); var deployPath = Path.Combine(DestinationRootDirectoryPath, ApplicationDirectoryName); TestLogger?.WriteLine($"[RemoteService]: Publishing to {deployPath}."); var process = new Process(); var startInfo = new ProcessStartInfo(); startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.UseShellExecute = false; startInfo.FileName = "dotnet.exe"; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.Arguments = $"publish {projectFile} --configuration Release --runtime win-x64 --framework {framework} --output {deployPath}"; process.StartInfo = startInfo; //We cannot run dotnet publish against the same directory concurrently. //Doing so causes the publish job to fail because it can't obtain a lock on files in the obj and bin directories. lock (GetPublishLockObjectForCoreApp()) { process.Start(); var processOutput = new ProcessOutput(TestLogger, process, true); const int timeoutInMilliseconds = 3 * 60 * 1000; if (!process.WaitForExit(timeoutInMilliseconds)) { TestLogger?.WriteLine($"[RemoteService]: PublishCoreApp timed out while waiting for {ApplicationDirectoryName} to publish after {timeoutInMilliseconds} milliseconds."); try { //This usually happens because another publishing job has a lock on the file(s) being copied. //We send a termination request because we no longer want dotnet publish to continue to copy files //when there's a good chance that at least some of the files are missing. //We can only use "kill" to request termination here, because there isn't a "close" option for non-GUI apps. process.Kill(); } catch (Exception e) { TestLogger?.WriteLine($"======[RemoteService]: PublishCoreApp failed to kill process that publishes {ApplicationDirectoryName} with exception ====="); TestLogger?.WriteLine(e.ToString()); TestLogger?.WriteLine($"-----[RemoteService]: PublishCoreApp failed to kill process that publishes {ApplicationDirectoryName} end of exception -----"); } } else { Console.WriteLine($"[{DateTime.Now}] dotnet.exe exits with code {process.ExitCode}"); } processOutput.WriteProcessOutputToLog("[RemoteService]: PublishCoreApp"); if (!process.HasExited || process.ExitCode != 0) { var failedToPublishMessage = "Failed to publish Core application"; TestLogger?.WriteLine($"[RemoteService]: {failedToPublishMessage}"); throw new Exception(failedToPublishMessage); } } Console.WriteLine($"[{DateTime.Now}] Successfully published {projectFile} to {deployPath}"); }
public override void Start(string commandLineArguments, bool captureStandardOutput = false, bool doProfile = true) { var arguments = UsesSpecificPort ? $"--port={Port} {commandLineArguments}" : commandLineArguments; var applicationFilePath = DestinationApplicationExecutablePath; var profilerFilePath = Path.Combine(DestinationNewRelicHomeDirectoryPath, @"NewRelic.Profiler.dll"); var newRelicHomeDirectoryPath = DestinationNewRelicHomeDirectoryPath; var profilerLogDirectoryPath = Path.Combine(DestinationNewRelicHomeDirectoryPath, @"Logs"); var startInfo = new ProcessStartInfo { Arguments = arguments, FileName = applicationFilePath, UseShellExecute = false, WorkingDirectory = DestinationApplicationDirectoryPath, RedirectStandardOutput = captureStandardOutput, RedirectStandardError = captureStandardOutput, RedirectStandardInput = RedirectStandardInput }; startInfo.EnvironmentVariables.Remove("COR_ENABLE_PROFILING"); startInfo.EnvironmentVariables.Remove("COR_PROFILER"); startInfo.EnvironmentVariables.Remove("COR_PROFILER_PATH"); startInfo.EnvironmentVariables.Remove("NEWRELIC_HOME"); startInfo.EnvironmentVariables.Remove("NEWRELIC_PROFILER_LOG_DIRECTORY"); startInfo.EnvironmentVariables.Remove("NEWRELIC_LICENSEKEY"); startInfo.EnvironmentVariables.Remove("NEW_RELIC_LICENSE_KEY"); startInfo.EnvironmentVariables.Remove("NEW_RELIC_HOST"); startInfo.EnvironmentVariables.Remove("CORECLR_ENABLE_PROFILING"); startInfo.EnvironmentVariables.Remove("CORECLR_PROFILER"); startInfo.EnvironmentVariables.Remove("CORECLR_PROFILER_PATH"); startInfo.EnvironmentVariables.Remove("CORECLR_NEWRELIC_HOME"); if (!doProfile) { startInfo.EnvironmentVariables.Add("CORECLR_ENABLE_PROFILING", "0"); } else if (IsCoreApp) { startInfo.EnvironmentVariables.Add("CORECLR_ENABLE_PROFILING", "1"); startInfo.EnvironmentVariables.Add("CORECLR_PROFILER", "{36032161-FFC0-4B61-B559-F6C5D41BAE5A}"); startInfo.EnvironmentVariables.Add("CORECLR_PROFILER_PATH", profilerFilePath); startInfo.EnvironmentVariables.Add("CORECLR_NEWRELIC_HOME", newRelicHomeDirectoryPath); if (UseTieredCompilation) { startInfo.EnvironmentVariables.Add("COMPlus_TieredCompilation", "1"); } } else { startInfo.EnvironmentVariables.Add("COR_ENABLE_PROFILING", "1"); startInfo.EnvironmentVariables.Add("COR_PROFILER", "{71DA0A04-7777-4EC6-9643-7D28B46A8A41}"); startInfo.EnvironmentVariables.Add("COR_PROFILER_PATH", profilerFilePath); startInfo.EnvironmentVariables.Add("NEWRELIC_HOME", newRelicHomeDirectoryPath); } if (AdditionalEnvironmentVariables != null) { foreach (var kp in AdditionalEnvironmentVariables) { startInfo.EnvironmentVariables.Add(kp.Key, kp.Value); } } startInfo.EnvironmentVariables.Add("NEWRELIC_PROFILER_LOG_DIRECTORY", profilerLogDirectoryPath); RemoteProcess = new Process(); RemoteProcess.StartInfo = startInfo; RemoteProcess.Start(); if (RemoteProcess == null) { throw new Exception("Process failed to start."); } CapturedOutput = new ProcessOutput(TestLogger, RemoteProcess, captureStandardOutput); if (RemoteProcess.HasExited && RemoteProcess.ExitCode != 0) { if (captureStandardOutput) { CapturedOutput.WriteProcessOutputToLog("[RemoteService]: Start"); } throw new Exception("App server shutdown unexpectedly."); } WaitForAppServerToStartListening(RemoteProcess, captureStandardOutput); }