Opening and closing background process using Unity and ProcessStartInfo - c#

I have been trying to write a quick script for my unity VR game to begin recording from an Azure Kinect camera at runtime, and close this script/recording on the close of application. To run their demo recording application, you run k4arecorder.exe output.mkv in a command prompt, and then pressing Ctrl-C to close the camera, which allows the program to save the file properly (see Azure Kinect SDK).
I have been able to successfully open the script and begin recording from the camera with the following code, but I have not been able to enter Ctrl-C (or any text at all) on the popup command prompt in order to stop the camera from running. And I can't use Process.StandardInput.Close() as I am running this with useShellExecute=True
The .exe saves the camera recording after Ctrl-C input, so I do need to close the stdin somehow before stopping the program entirely.
ProcessStartInfo startInfo;
Process process;
void Start()
{
startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Program Files\Azure Kinect SDK v1.4.1\tools\k4arecorder.exe";
startInfo.Arguments = System.IO.Directory.GetCurrentDirectory() + "\\output_testing.mkv";
process = new Process {StartInfo = startInfo};
process.Start();
}
I've also tried a different approach, redirecting the StandardInput, but then I don't see any text at all on the popup command prompt, and my attempts to close stdin and print anything to the command prompt have also not worked. For example, I never see anything in the command prompt running:
ProcessStartInfo startInfo;
Process process;
void Start()
{
startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Program Files\Azure Kinect SDK v1.4.1\tools\k4arecorder.exe";
startInfo.Arguments = System.IO.Directory.GetCurrentDirectory() + "\\output_testing.mkv";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.CreateNoWindow = false;
process = new Process {StartInfo = startInfo};
process.Start();
process.StandardInput.WriteLine("testing");
string output = process.StandardOutput.ReadToEnd();
UnityEngine.Debug.Log(output);
}
void OnApplicationQuit()
{
// this will just perpetually wait until I close the window cause cntrl-c not going thru
process.StandardInput.Close();
process.WaitForExit();
process.Close();
}
Any tips immensely appreciated! I feel like there must be a way past this with either method, but I'm coming up short. This is Unity 2019.4.1f1 and Azure Kinect SDK v1.4.1 (though I don't think this is a bug).

Hi one thing that worked for me is using:
void OnApplicationQuit() { process.CloseMainWindow(); }

Related

check for process end to close splashscreen

I have a winform app in C# with has to create an SQLLocalDB instance at first run.
I saw that this process was taking some time in some older PC´s and some users thought that the app had crashed.
I created a splashscreen form that lets the user know that the app is creating the instance but i dont know how i cant check when the process has ended and close the splashscreen.
I have a class with the following code to create the instance:
static private void ExecCmdInstance()
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/c sqllocaldb create MSSQLLocalDB -s";
process.StartInfo = startInfo;
process.Start();
}
Can anyone point me in the right direction please?
Thanks in advance.
You could use:
process.WaitForExit();
But be aware that it will block your gui thread. You might start the process on a different thread, so your gui isn't blocked.

Running a cmd command from within my C# code

I'm currently hosting OSRM locally on my machine to build a routing application. When the application starts, a bool ServiceAvailable is checked with a test query to see if the application is available and running locally. I want to be able to start the OSRM application should this bool return false. I found a StackOverflow link with a similar issue and tried to implement it, but the application doesn't load. Here's my current code:
private void StartOSRMService()
{
Process process = new Process();
process.StartInfo.WorkingDirectory = #"C:\";
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/c cd users/james/desktop/osrm/osrm-backend/osrm_release";
process.StartInfo.Arguments = "/c osrm-routed wales-latest.osrm";
}
The method is ran but the service never starts. In other methods, my code breaks due to a Http.Web request error, due to the lack of the service.
You can try the following:
private void StartOSRMService()
{
var startInfo = new ProcessStartInfo(#"C:\users\james\desktop\osrm\osrm-backend\osrm_release\osrm-routed.exe");
startInfo.WorkingDirectory = #"C:\users\james\desktop\osrm\osrm-backend\osrm_release";
startInfo.UseShellExecute = false;
startInfo.Arguments = "wales-latest.osrm";
Process.Start(startInfo);
}
More info on Process.Start()
Also, based on your original StartInfo.Arguments, the "/C" tells to console to terminate after the command has been executed, thus, if the "osrm-routed" is the service that needs to run in the console, and the console is terminated, then the application itself will also terminate when the console terminates.

HandbrakeCLI wont automate via C# process

I am trying to automate HandbrakeCLI using C# via the System.Diagnostics.Process class. However, as long as my program is trying to run the process, it seems like the process never advances.
Here is my process setup:
Process process = new System.Diagnostics.Process();
ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.FileName = parameters.HandbrakeLocation;
startInfo.Arguments = arguments;
process.StartInfo = startInfo;
process.Start();
string output = string.Empty;
while ((output = process.StandardOutput.ReadLine()) != null)
{
Debug.WriteLine(output);
}
process.WaitForExit();
HandbrakeCLI.exe does appear in my processes list. The Debug.WriteLine(output); line continually prints out "Encoding: task 1 of 1, 0.00 %" and the process never completes. If I kill my C# app then HandbrakeCLI instantly shoots up from 7,000k in memory to 145,000k and then does the encoding that I want it to do. Its like my C# app is holding it back.
I have tried to use Read() instead of ReadLine() and I have tried flushing the StandardOutput stream before and after the read with no success. I have a suspicion that since HandbrakeCLI overwrites stdout when it writes the encoding progress, that it won't act like a normal process when automated via C#.
I figured it out. I was redirecting stderr to my C# application, but not consuming it. The process was hanging until stderr was consumed.

How to open Putty Process without it opens in another window

using this Code
Process process = new Process();
// p.EnableRaisingEvents = true;
process.EnableRaisingEvents = true;
process.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.LoadUserProfile = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = #"C:\putty.exe"; ; // Gets or sets the application or document to start.
process.StartInfo.Arguments = "-serial com31 -sercfg 9600,8,n,1,N";//Gets or sets the set of command-line arguments to use when starting the application
Thread.Sleep(1000);
process.Start();//Starts (or reuses) the process resource that is specified by the StartInfo property of this Process component and associates it with the component.
process.BeginOutputReadLine();
process.WaitForExit(); // wait forever with ping
I'm trying to open putty in console application , but any timr I use it it opens in New windows and I cant get to output of the process using process.OutputDataReceived event
I'm using code very similar to this to open Iperf and it works fine
What am I missing here ?
Putty is not a console application and therefore does not provide output on it's stdout and stderr streams.
And since it is a windowed application it does not care whether you start it with the CreateNoWindow flag. Try and start notepad.exe with that flag, you will see it appearing obviously.
There is however a programm by the creators of Putty that provides the functionality you need.
It's called Plink.exe and you can download it on their homepage

ProcessStartInfo.UseShellExecute = true and waiting for process exit

I want to use shell executable in order to respect user preferences of application to be started, but I also need to know when that particular application is closed.
Process editProcess = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = filename;
startInfo.Verb = "edit";
startInfo.UseShellExecute = true;
editProcess.StartInfo = startInfo;
// start the default editor
editProcess.Start();
editProcess.WaitForExit();
WaitForExit seems to return when the shell process exits and not when the real process exits.
Is there a better way of knowing when started application is exited than manually parsing registry, finding correct application to start and explicitly start that app without shell execute?
Handle the process exited event:
editProcess.Exited += process_Exited;

Categories

Resources