Skip to content

.NET Core 8 Process StandardIn and Close() Failures #113289

@Crash0v3r1de

Description

@Crash0v3r1de

Description

I know I read an article roughly about this issue posted in 2021 but mine might be a little different and the issue thread auto closed overtime so I figured it's worth reporting if it is a bug which I think it is? I'm starting a process inside a static class so other classes can call on it without initializing a new instance since it's handling a process I want to keep running until told otherwise from within my program.

The code itself is super straight forward, I've google for literal hours and kind of out of ideas. I even tried the kernel32.dll GenerateConsoleCtrlEvent() which did nothing whatsoever. The binary I'm calling spawns it's own child process as well which I'm not sure if that matters.

MyApp.exe
->Server.exe
->ServerListener.exe

Reproduction Steps

Using Visual Studio 2022 Community with .NET Core >= 8 on a typical WinForm project.
Code causing it is bellow

private static Process server;

public static void StartServer(){
ProcessStartInfo args = new ProcessStartInfo();
args.Arguments = $"?Port={ListenerCoreSettings.ServerPort}";
args.UseShellExecute = false;
args.RedirectStandardOutput = true;
args.RedirectStandardError = true;
args.RedirectStandardInput = true;
args.CreateNoWindow = true;
args.WindowStyle = ProcessWindowStyle.Hidden;
args.FileName = ListenerCoreSettings.serverExe;
server = new Process();
server.StartInfo = args;
server.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
    if (!String.IsNullOrEmpty(e.Data))
    {
        Form1.AppendConsoleEntry(e.Data); // Basic Winform
    }
});
server.ErrorDataReceived += new DataReceivedEventHandler((sender, e) =>
{
    if (!String.IsNullOrEmpty(e.Data))
    {
        Form1.AppendConsoleEntry(e.Data); // Basic Winform
    }
});
server.Start(); // server itself is an external binary (visual c++ 2015-2022 redistrib)
server.BeginOutputReadLine();
server.BeginErrorReadLine();

new Thread(() => {
// simple thread for testing closing options easier
    while (true) {
        Form1.AppendConsoleEntry(server.HasExited.ToString()); // Debug verifying the Proccess object is functioning after start
        if (!ListenerCoreSettings.AllowServerRunning) {                        
            server.Close(); // the child process started from mine does nothing, no errors and runtime is normal in debug and publish
            server.StandardInput.Close(); // StandardIn not redirected error
            using(StreamWriter sw = server.StandardInput){
               sw.WriteLine("\x3"); // Same StandardIn not redirected error
           }
        }
        Thread.Sleep(5000);
    }
}).Start();
}

Expected behavior

I would expect
server.Close()
to gracefully exit like a normal CTRL+C entry as if from a user having the console window open

As for calling the StandInput itself direct (Async or not) as well as within a StreamWriter instance sending \x3 should also handle graceful exit like sending a CTRL+C manually - unless there's something myself and ALOT of other threads are missing.

Actual behavior

server.CLose() Does nothing, no errors during runtime
server.StandardInput.Close() "StandardIn has not been redirected."
using(StreamWriter sw = server.StandardInput){ sw.WriteLine("\x3") } "StandardIn has not been redirected."

Regression?

I've definitely done this in .NET core like 3 back in the day as well as .NET Framework 3.5/4.7/4.8 also back in the day.

Known Workarounds

None I can find so far unfortunately.

Configuration

Target Framework - .NET 8
Target OS - WIndows (being ran on WIndows 11 23H2 machine)
x64 system (i9 14th gen)
No clue if it is specific to my configuration

Other information

I initially was sending the Process object from one static class to another so that class could be running the monitoring thread and handle when it should close the program but when I started running .Close and StandardIn it was throwing errors so I moved to the same class and made .Close happy but not StandardIn. I'm very sorry if this has been a common submission but I purely cannot find any snippets that will work after literally hours of browsing, testing, failing, repeat.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions