-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Description
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.
- ClientGrpc (No problems)
- 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
- 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) - Install .NET runtimes on target host PC
- Setup VS Remote Debugging tools and start service on target host PC.
- Map remote drive on local PC and setup Client / Server gRPC projects accordingly.
- Run project (multi-launch)
- Send client Command (defined via .proto file) to start and open the remote target process on the gRPC server.
- 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?