How to raise an event when a process is done in Powershell? - c#

I would like to use Powershell to Start an application with some options of Start-Process as the code and then close the application after the process is done. The process is to measure some signals.
At first, this process is done by the C# code but I think this function can be converted to Powershell. However I dont' know how to do that, especially, with the Process.Exited and Process.EnableRaisingEvents.
Please help me.
Thank you in advance.
public void Execute_process(string console_path, string arg1)
{
try
{
//プロセス作成
p = new Process();
p.StartInfo.FileName = console_path + "\\" + "IQfactRun_Console.exe";
//p.StartInfo.Verb = "RunAs";
p.StartInfo.Arguments = " -run " + ini["IQFACT", "flow_folder"] + "\\" + arg1;
Debug.WriteLine("arg:" + " -run " + ini["IQFACT", "flow_folder"] + "\\" + arg1);
p.StartInfo.CreateNoWindow = false;
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Minimized;
p.StartInfo.UseShellExecute = true;
p.StartInfo.WorkingDirectory = ini["IQFACT", "Console_file"];
p.StartInfo.RedirectStandardError = false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.RedirectStandardInput = false;
p.Exited += new EventHandler(Process_exited);
p.EnableRaisingEvents = true;
//プロセス実行状態に設定
run_status = true;
//外部プロセス起動
p.Start();
}
catch (Exception ex)
{
Debug.WriteLine("例外発生:" + ex);
}
}

Related

Unable to open Visual Studio Command Prompt pragmatically using VS 2015

I want to run visual studios command programmatically.I have tried the above code but no help.All I am getting is a command prompt with my project`s directory open.
I have used Execute("VS140COMNTOOLS") as input.
private void Execute(string vsEnvVar) {
var vsInstallPath = Environment.GetEnvironmentVariable(vsEnvVar);
if (Directory.Exists(vsInstallPath)) {
var filePath = vsInstallPath + "vsvars32.bat";
if (File.Exists(filePath)) {
//start vs command process
Process proc = new Process();
var command = Environment.GetEnvironmentVariable("ComSpec");
command = #"" + command + #"";
//var batfile = #"E:\Test\vstest.bat";
var args = string.Format("/S/K \" \"{0}\" \"", filePath);
proc.StartInfo.FileName = command;
proc.StartInfo.Arguments = args;
//proc.StartInfo.RedirectStandardInput = true;
//proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.UseShellExecute = false;
proc.Start();
} else {
Console.WriteLine("File Does not exists " + filePath);
}
}
}
Try this:
private Process Execute(string vsEnvVar)
{
Process process = new Process();
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe");//assume location is in path. Otherwise use ComSpec env variable
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo = psi;
// attach output events
process.ErrorDataReceived += new DataReceivedEventHandler(process_ErrorDataReceived);
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.StartInfo = psi;
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.StandardInput.WriteLine(string.Format("call \"%{0}%vsvars32.bat\""), vsEnvVar);
process.StandardInput.Flush();
return process;
}
Now you can execute any commands by writing to process.StandardInput
process.StandardInput.WriteLine(#"msbuild c:\MySolution.sln /t:Clean");

Process Wait For Exit not work

I'm using the below code to download from youtube using youtube-dl python script.
string pythonPath = #"C:\Python35\python.exe";
string ydl = #"C:\Y\ydl\youtube-dl";
string tempLocation = Server.MapPath("/ydl/");
string Output = "";
string Error = "";
int numOutputLines = 0;
int numErrorLines = 0;
using (Process process = new Process())
{
process.EnableRaisingEvents = true;
process.StartInfo.ErrorDialog = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.FileName = pythonPath;
process.StartInfo.WorkingDirectory = tempLocation;
process.StartInfo.Arguments = ydl + " --output test.mp4 --force-ipv4 -f bestvideo[ext=mp4]+bestaudio[ext=m4a] \"" + Url + "\"";
process.StartInfo.Verb = "runas";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
StringBuilder output = new StringBuilder();
StringBuilder error = new StringBuilder();
using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
{
process.OutputDataReceived += (sender, e) =>
{
if (e.Data == null)
{
outputWaitHandle.Set();
}
else
{
numOutputLines++;
this.Context.Response.Write(Environment.NewLine + "[" + numOutputLines.ToString() + "] - " + e.Data);
output.AppendLine("[" + numOutputLines.ToString() + "] - " + e.Data);
}
};
process.ErrorDataReceived += (sender, e) =>
{
if (e.Data == null)
{
errorWaitHandle.Set();
}
else
{
numErrorLines++;
this.Context.Response.Write(Environment.NewLine + "[" + numErrorLines.ToString() + "] - " + e.Data);
error.AppendLine("[" + numErrorLines.ToString() + "] - " + e.Data);
}
};
//process.Exited += (s, a) =>
//{
// process.Close();
//};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
//process.WaitForExit();
Process[] curProcess = Process.GetProcessesByName("youtube-dl");
Process youtubeProcess = curProcess.FirstOrDefault();
while (!youtubeProcess.HasExited)
{
Thread.Sleep(100);
}
Output = output.ToString();
Error = error.ToString();
process.Close();
}
}
I used the proccess in this way because I want to have the percentage of youtube-dl script for showing in my client side progress bar.
But there are some problems and it's that WaitForExit is not working. I read from other topics that this issue is related to wait in process not working for child process(I mean in my way, the wait for exit works for python not for youtube-dl script)
What should I do?
Since you are interested in a child process maybe you an try to poll on the youtube process by using the method:
Process.GetProcessesByName(string processName);
Something like this:
Process[] curProcess = Process.GetProcessesByName("your youtube process name");
Process youtubeProcess = curProcess.FirstOrDefault(); // Get here the right process instance
while (!youtubeProcess.HasExited)
{
Thread.Sleep(100);
}

Run WinSat Command C#

I am trying to run cmd winsat -drive c programmatically
The code below is only returning "Windows System Assessment Tool" the first line of the output but is not letting the winsat run and return the rest of the output
I am looking for the entire output to be returned shown here
The code I am using is this
public string RunAndOutput(object command)
{
var procStartInfo =
new ProcessStartInfo("winsat", "/c " + "-drive c");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
var proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
proc.WaitForExit(); // Wait for everything to finish
return result;
}
You will need to wait for the process to exit using WaitForExit(), like this:
public string RunAndOutput(object command)
{
var procStartInfo =
new ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
var proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
proc.WaitForExit(); // Wait for everything to finish
return result;
}

cmd command in c#

I want to import a csv file to mongodb by using mongoimport in C#. So I implement this method
public bool importCSV(string filepath, string db, string collectionName){
string result="";
try
{
ProcessStartInfo procStart = new ProcessStartInfo("cmd", "C:/MongoDB/Server/3.0/bin/mongoimport -d " + db + " -c " + collectionName + " --type csv --file " + filepath );
procStart.RedirectStandardOutput = true;
procStart.CreateNoWindow = false;
Process proc = new Process();
proc.StartInfo = procStart;
proc.Start();
result += proc.StandardOutput.ReadToEnd();
}
catch(Exception e){
Console.WriteLine(e.ToString());
}
if (!result.Equals("")){
return true;
}
return false;
}
When I run command itself, I can import file to MongoDB. But by using C#, method returns false.
Can anyone help me to solve this problem?
SOLUTION!!!
public bool importCsv(string filepath, string collectionName){
string result ="";
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:/MongoDB/Server/3.0/bin/mongoimport.exe";
startInfo.Arguments = #" -d test -c " + collectionName + " --type csv --file " + filepath + " --headerline";
Process proc = new Process();
proc.StartInfo = startInfo;
proc.Start();
result += "ddd";
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
if (!result.Equals(""))
{
return true;
}
return false;
}
try something like this:
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
result+=e.Data;
}
});
process.Start();
// Asynchronously read the standard output of the spawned process.
// This raises OutputDataReceived events for each line of output.
process.BeginOutputReadLine();
process.WaitForExit();
process.Close();

Run a console application from a windows Form

I have a windows console app (that accepts parameters) and runs a process.
I was wondering if there was any way to run this app from within a windows form button click event. I would like to pass an argument to it as well.
Thanks
Just use System.Diagnostics.Process.Start with the path to the console application, and the parameters as the second argument.
Assuming you have a form with a multiline textbox called txtOutput.....
private void RunCommandLine(string commandText)
{
try
{
Process proc = new Process();
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c " + commandText;
txtOutput.Text += "C:\\> " + commandText + "\r\n";
proc.Start();
txtOutput.Text += proc.StandardOutput.ReadToEnd().Replace("\n", "\r\n");
txtOutput.Text += proc.StandardError.ReadToEnd().Replace("\n", "\r\n");
proc.WaitForExit();
txtOutput.Refresh();
}
catch (Exception ex)
{
txtOutput.Text = ex.Message;
}
}
You'll want to use System.Diagnostics.Process

Categories

Resources