I have a software library which targets console applications. I would like to run a slim set of integration tests that use the windows Console in a headless runner that would ideally be run on our build server and in the resharper test runner.
To make this work, I need the actual System.Console
calls to be executed in the test (so they can't be conditionally commented out.)
When the tests call something that the requires the stdout handle, e.g. Console.SetCursorPosition
, an exception is generated: System.IO.IOException: 'The handle is invalid'
I assumed I could just do a pinvoke and call FreeConsole
and AllocConsole
and this would allow me to call the relevant methods. Unfortunately this doesn't appear to be the case.
At the moment I can successfully Free, Alloc, and redirect console output back to STDOUT but this doesn't change the exception behaviour. Any ideas?
I'm redirecting STDOUT back to CONOUT using the following:-
var stdoutFile = ExternalMethods.CreateFile("CONOUT$", FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero);
var handle = new Microsoft.Win32.SafeHandles.SafeFileHandle(stdoutFile, true);
if (handle.IsInvalid)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
if (!ExternalMethods.SetStdHandle(-11, handle))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
I got this working in the end. It was necessary to create a sub-process with CREATE_NO_WINDOW flags, wait until the process had started a new console session, and then attach to the sub-process.