int exit_code = exe_start(argc, argv);
- // Flush traces before exit - just to be sure, and also if we're showing a popup below the error should show up in traces
- // by the time the popup is displayed.
+ // Flush traces before exit - just to be sure
trace::flush();
#if defined(_WIN32) && defined(FEATURE_APPHOST)
executable_name = get_filename(executable_name);
}
+ trace::verbose(_X("Creating a GUI message box with title: '%s' and message: '%s;."), executable_name.c_str(), g_buffered_errors.c_str());
+
+ // Flush here so that when the dialog is up, the traces are up to date (specifically when they are redirected to a file).
+ trace::flush();
+
::MessageBoxW(NULL, g_buffered_errors.c_str(), executable_name.c_str(), MB_OK);
}
#endif
// See the LICENSE file in the project root for more information.
using Microsoft.DotNet.Cli.Build.Framework;
+using System;
+using System.IO;
namespace Microsoft.DotNet.CoreSetup.Test.HostActivation
{
return command.EnvironmentVariable(Constants.HostTracing.TraceLevelEnvironmentVariable, "1");
}
+ public static Command EnableHostTracingToFile(this Command command, out string filePath)
+ {
+ filePath = Path.Combine(TestArtifact.TestArtifactsPath, "trace" + Guid.NewGuid().ToString() + ".log");
+ if (File.Exists(filePath))
+ {
+ File.Delete(filePath);
+ }
+
+ return command
+ .EnableHostTracing()
+ .EnvironmentVariable(Constants.HostTracing.TraceFileEnvironmentVariable, filePath);
+ }
+
public static Command EnableTracingAndCaptureOutputs(this Command command)
{
return command
.CaptureStdOut()
.Start();
- IntPtr windowHandle = WaitForPopupFromProcess(command.Process);
- Assert.NotEqual(IntPtr.Zero, windowHandle);
+ WaitForPopupFromProcess(command.Process);
// In theory we should close the window - but it's just easier to kill the process.
// The popup should be the last thing the process does anyway.
UseBuiltAppHost(appExe);
MarkAppHostAsGUI(appExe);
- string traceFilePath = Path.Combine(Path.GetDirectoryName(appExe), "trace.log");
-
+ string traceFilePath;
Command command = Command.Create(appExe)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .EnvironmentVariable("COREHOST_TRACEFILE", traceFilePath)
+ .EnableHostTracingToFile(out traceFilePath)
.Start();
- IntPtr windowHandle = WaitForPopupFromProcess(command.Process);
- Assert.NotEqual(IntPtr.Zero, windowHandle);
+ WaitForPopupFromProcess(command.Process);
// In theory we should close the window - but it's just easier to kill the process.
// The popup should be the last thing the process does anyway.
result.Should().Fail()
.And.FileExists(traceFilePath)
+ .And.FileContains(traceFilePath, "Creating a GUI message box with")
.And.FileContains(traceFilePath, "This executable is not bound to a managed DLL to execute.");
+
+ FileUtils.DeleteFileIfPossible(traceFilePath);
}
[Fact]
UseBuiltAppHost(appExe);
MarkAppHostAsGUI(appExe);
+ string traceFilePath;
Command command = Command.Create(appExe)
- .EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnableHostTracingToFile(out traceFilePath)
.CaptureStdOut()
.CaptureStdErr()
.EnvironmentVariable(Constants.DisableGuiErrors.EnvironmentVariable, "1")
Assert.True(false, "The process failed to exit in the alloted time, it's possible it has a dialog up which should not be there.");
}
+
+ commandResult
+ .Should().Fail()
+ .And.FileExists(traceFilePath)
+ .And.FileContains(traceFilePath, "Gui errors disabled, keeping errors in stderr.")
+ .And.NotFileContains(traceFilePath, "Creating a GUI message box with")
+ .And.FileContains(traceFilePath, "This executable is not bound to a managed DLL to execute.");
+
+ FileUtils.DeleteFileIfPossible(traceFilePath);
}
#if WINDOWS
timeRemaining -= 100;
}
- Assert.True(
- windowHandle != IntPtr.Zero,
- $"Waited {longTimeout} milliseconds for the popup window on process {process.Id}, but none was found." +
- $"{Environment.NewLine}{diagMessages.ToString()}");
-
- Assert.True(
- timeRemaining > (longTimeout - timeout),
- $"Waited {longTimeout - timeRemaining} milliseconds for the popup window on process {process.Id}. " +
- $"It did show and was detected as HWND {windowHandle}, but it took too long. Consider extending the timeout period for this test.");
+ // Do not fail if the window could be detected, sometimes the check is fragile and doesn't work.
+ // Not worth the trouble trying to figure out why (only happens rarely in the CI system).
+ // We will rely on product tracing in the failure case.
return windowHandle;
}
public AndConstraint<CommandResultAssertions> FileContains(string path, string pattern)
{
- Execute.Assertion.ForCondition(System.IO.File.ReadAllText(path).Contains(pattern))
- .FailWith("The command did not write the expected result '{0}' to the file: {1}{2}", pattern, path, GetDiagnosticsInfo());
+ string fileContent = System.IO.File.ReadAllText(path);
+ Execute.Assertion.ForCondition(fileContent.Contains(pattern))
+ .FailWith("The command did not write the expected result '{0}' to the file: {1}{2}\nfile content: {3}", pattern, path, GetDiagnosticsInfo(), fileContent);
return new AndConstraint<CommandResultAssertions>(this);
}
public AndConstraint<CommandResultAssertions> NotFileContains(string path, string pattern)
{
- Execute.Assertion.ForCondition(!System.IO.File.ReadAllText(path).Contains(pattern))
- .FailWith("The command did not write the expected result '{1}' to the file: {1}{2}", pattern, path, GetDiagnosticsInfo());
+ string fileContent = System.IO.File.ReadAllText(path);
+ Execute.Assertion.ForCondition(!fileContent.Contains(pattern))
+ .FailWith("The command did not write the expected result '{1}' to the file: {1}{2}\nfile content: {3}", pattern, path, GetDiagnosticsInfo(), fileContent);
return new AndConstraint<CommandResultAssertions>(this);
}