Skip to content

Process - Unable to obtain output from redirected process when RedirectStandardInput is enabled #118752

@Latency

Description

@Latency

Description

Attempting to create a relay service proxy via gRPC executing a remote process that is acting as an interactive shell on target host.

The target process appears to be written in VC++.

The SDK to embedded hardware uses a plethora of .bat files to setup environment variables and then spawns an interactive shell process called 'rdi_xsct.exe'

I have obtained similar results when either opening a Process via the batch file or setting env variables in code via a cmd.exe + then writing input to launch the 'rdi_xsct.exe'.

The process loads, but the splash screen ascii output is not shown.

In addition, when I send commands to it via writeline(), I do not receive any stdoutput either.

If I set the ResirectStandardInput = false, the output is displayed as expected.

Issue:
Able to receive std output within a terminal console window via 'echo ' prior to the call "%RDI_BINROOT%/loader.bat" -exec rdi_xsct %CMDARGS%
--> E.g. "--exec " within the primary batch file which is complicating things.

Similarly, if I write my own mock emulator application, I can obtain the output properly as well.

The target process

Using VSRemote Debugging tools and x-compiling onto target server, I can launch gRPC and communicate via IPC just fine.

  1. ClientGrpc (No problems)
  2. ServerGrpc (No Problems)
    --> System.Diagnostics.Process (undetermined behavior) --> xsct.bat or rdi_xsct.exe. (no output)

... ... ... call "%RDI_BINROOT%/loader.bat" -exec rdi_xsct %CMDARGS% endlocal

Reproduction Steps

  1. Download and install Xilinx SDK (tools) from AMD on target host PC
    https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/embedded-design-tools/archive.html (v2018.3)
  2. Install .NET runtimes on target host PC
  3. Setup VS Remote Debugging tools and start service on target host PC.
  4. Map remote drive on local PC and setup Client / Server gRPC projects accordingly.
  5. Run project (multi-launch)
  6. Send client Command (defined via .proto file) to start and open the remote target process on the gRPC server.
  7. Observe splash screen output & error within callback delgates on System.Diagostics.Process (async) handling.

Expected behavior

Expect to have output be sent to both event invocator callbacks when RedirectStandardInput = true

        Environment.SetEnvironmentVariable("XILINX_SDK" , sdkPath,                      EnvironmentVariableTarget.Process);
        Environment.SetEnvironmentVariable("TCL_LIBRARY", $@"{sdkPath}\tps\tcl\tcl8.5", EnvironmentVariableTarget.Process);
        Environment.SetEnvironmentVariable("RDI_DATADIR", $@"{sdkPath}\data",           EnvironmentVariableTarget.Process);
        Environment.SetEnvironmentVariable("HDI_APPROOT", sdkPath,                      EnvironmentVariableTarget.Process);
        Environment.SetEnvironmentVariable("RDI_APPROOT", sdkPath,                      EnvironmentVariableTarget.Process);
        Environment.SetEnvironmentVariable("PATH"       , @"...",         EnvironmentVariableTarget.Process);;

        _psi = new ProcessStartInfo
        {
            FileName               = "cmd.exe",
            RedirectStandardInput  = true,  // <--- ISSUES  (Receives output when false)
            RedirectStandardError  = true,
            RedirectStandardOutput = true,
            UseShellExecute        = false,  // Enable redirection
            CreateNoWindow         = true,
            WorkingDirectory       = Path.GetDirectoryName(xilinxFileName)
        };

...

        p = new Process
        {
            StartInfo           = _psi,
            EnableRaisingEvents = true
        };

        p.OutputDataReceived += OnOutputDataReceived;
        p.ErrorDataReceived  += OnErrorDataReceived;

        p.Start();

        p.BeginOutputReadLine();
        p.BeginErrorReadLine();

        P.StandardInput.Writeline(xilinxFileName);

Expecting to receive the exact stdout/stderr on the conhost.exe terminal window when running the .bat file on the localhost or attempts to bypass .bat file and launch it directly.

Actual behavior

No StdOutput / StdError is being sent to the async callbacks registered when RedirectStandardInput = true.

RedirectStandardInput must be 'true' in order to write which is a requirement.
However, it be 'false' in order to receive StdOutput + Error reliably.

'cmd.exe' process is created which is expected to run the target process.

I have observed a 'conhost.exe' process being created for the terminal window app running the server as gRPC and opening the Process to the target assembly 'rdi_xsct.exe'.

Regression?

  • Tried both Async + Synchronous implementations. - Can get output OR input but not both within an active session.

  • Created an emulator in pure C# .exe to mock the interactive target process shell using Console R/W built in streams and that actually works just fine as intended.

  • Created a folder with all the .dll + .exe files for a slim down distro to test keeping the "rdi_xsct.exe" alive using PS or cmdTerminal.

  • Verified that the environment variables required are what was added into the code. (6x)

  • Opened a cmd terminal window in the aforementioned folder and copy + pasted the environment variables.
    This terminal window works as expected on its own.. however, does not work when opened via System.Diagnostics.Process.

Known Workarounds

Setting RedirectStandardInput = false will obtain output & error but inability to write to the StdInput stream. (throws an exception as intended)
Setting RedirectStandardInput = true will not display output/error as it appears hung/blocked + ability to write to the process. (restored)

Configuration

Which version of .NET is the code running on? Running 'net10.0-windows' (Latest) [10.0.0-preview.7.25380.108]
Also tried 'net9.0-windows'

What OS and version, and what distro if applicable? Windows 11 (client / server)

What is the architecture (x64, x86, ARM, ARM64)? x64

Using gRPC (latest) w/ Kestral hostbuilder loading.

Other information

Also, tried creating standalone desktop emulator minus gRPC code to running test DataReveived callbacks on the remote host similarly.. and is still failing within System.Diagnostics.Process.

Why can I not get the output just as it would if I were running a standard PS or cmd terminal on the target's localhost?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions