C# stop a process - c#

I would to be able to stop a typeperf process i started in c# for remote machines.
What i got so far is:
ProcessStartInfo proc = new ProcessStartInfo();
public void startLogs()
{
for (int i = 0; i < remote_machines_num; i++)
{
string line = " -s " + machines[i]
+ " -si 5 \"\\Processor(_Total)\\% Processor Time\" -o C:\\logs\\"
+ machines[i] + ".csv";
proc.FileName = #"C:\WINDOWS\SYSTEM32\typeperf.exe";
proc.Arguments = line;
Process.Start(proc);
}
}
this really starts all monitors - but i would like to write a function that will stop monitoring and close all windows - how can i do that? thanks!

Get a reference to the started process and Kill() it.
var theRunningProc = Process.Start(proc);
theRunningProc.Kill();

Are you looking for this
http://alperguc.blogspot.com/2008/11/c-process-processgetprocessesbyname.html

Related

Execute jar file in c#

I have a problem with executing the jar file in c#.
This jar file is epubcheck.jar
here is my code to run the file
public string IdpfValidateEpub(string epub)
{
try
{
string result = null;
string epubCheckPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "epubcheck.jar");
string arguments = "java -jar" + " \"" + epubCheckPath + "\"" + " \"" + epub + "\"";
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
//strCommand is path and file name of command to run
pProcess.StartInfo.FileName = #"cmd.exe";
//strCommandParameters are parameters to pass to program
pProcess.StartInfo.Arguments = arguments;
Debug.WriteLine("arguments: " + pProcess.StartInfo.Arguments);
pProcess.StartInfo.UseShellExecute = false;
pProcess.StartInfo.CreateNoWindow = false;
//Set output of program to be written to process output stream
pProcess.StartInfo.RedirectStandardOutput = true;
//Start the process
pProcess.Start();
//Get program output
result = pProcess.StandardOutput.ReadToEnd();
//Wait for process to finish
pProcess.WaitForExit();
return result;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
throw ex;
}
}
But the program is not running at all. I also set the property to show the window. So i can see if its running or not. But it only shows the command prompt like this
I also printed the arguments i passed in the System.Diagnostics.Process in order to check if the arguments are correct.
After the program printed the arguments. i just copied it and paste in the command prompt. And the program works as expected. But why does it doesn't work in my c# code?
Thank you so much.
Java is a program in its own right, so you don't actually need cmd.exe to run it.
Change your arguments to the following so that you're passing the arguments for java:
string arguments = "-jar" + " \"" + epubCheckPath + "\"" + " \"" + epub + "\"";
And then simply start java instead of cmd:
pProcess.StartInfo.FileName = #"java";

launch gnuplot from c#, change directory and load multiple gnuplot scripts

I want to generate a couple of hundreds .txt scripts in a C# app, launch GnuPlot and generate .png graphs for each of the scripts I have.
I can launch GnuPlot from C# with the following code:
Process gnuPlotProcess = new Process();
gnuPlotProcess.StartInfo = new ProcessStartInfo(#"C:\Program Files\gnuplot\bin\wgnuplot.exe");
gnuPlotProcess.Start();
The first problem appears when I'm trying to change the current directory, adding this line of code before starting the process:
gnuPlotProcess.StartInfo.Arguments = "cd '" + scriptsPath + "'";
Now GnuPlot doesn't start.
The second problem, which I was able to test working on GnuPlot's default current directory, is when attempting to pass the "load 'script_xxx.txt'" command. Here is the complete code (inspiration from Plotting graph from Gunplot in C#):
Process gnuPlotProcess = new Process();
gnuPlotProcess.StartInfo = new ProcessStartInfo(#"C:\Program Files\gnuplot\bin\wgnuplot.exe");
gnuPlotProcess.StartInfo.RedirectStandardInput = true;
gnuPlotProcess.StartInfo.UseShellExecute = false;
theProcess.Start();
StreamWriter sw = gnuPlotProcess.StandardInput;
sw.WriteLine("load '" + pathToScript + "'");
sw.Flush();
The script that is found on pathToScript should create a .png file, and it works when being launched directly from gnuPlot. But from code, nothing happens.
Any help would be appreciated.
I hope this code will help you:
int N = 1000;
string dataFile = "data.txt"; // one data file
string gnuplotScript = "gnuplotScript.plt"; // gnuplot script
string pngFile = "trajectory.png"; // output png file
// init values
double x = 0, y = 0;
// random values to plot
Random rnd = new Random();
StreamWriter sw = new StreamWriter(dataFile);
// US output standard
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
// generate data for visualisation
for (int i = 0; i < N; i++)
{
x += rnd.NextDouble() - 0.5;
y += rnd.NextDouble() - 0.5;
sw.WriteLine(x.ToString("F3") + "\t" + y.ToString("F3"));
}
sw.Close();
// you can download it from file
string gnuplot_script = "set encoding utf8\n" +
"set title \"Random trajectory\"\n" +
"set xlabel \"Coordinate X\"\n" +
"set ylabel \"Coordinate Y\"\n" +
"set term pngcairo size 1024,768 font \"Arial,14\"\n" +
"set output \"pngFile\"\n" +
"plot 'dataFile' w l notitle\n" +
"end";
// change filenames in script
gnuplot_script = gnuplot_script.Replace("dataFile", dataFile);
gnuplot_script = gnuplot_script.Replace("pngFile", pngFile);
// write sccript to file
sw = new StreamWriter(gnuplotScript, false, new System.Text.UTF8Encoding(false));
sw.WriteLine(gnuplot_script);
sw.Close();
// launch script
ProcessStartInfo PSI = new ProcessStartInfo();
PSI.FileName = gnuplotScript;
string dir = Directory.GetCurrentDirectory();
PSI.WorkingDirectory = dir;
using (Process exeProcess = Process.Start(PSI))
{
exeProcess.WaitForExit();
}
// OPTION: launch deafault program to see file
PSI.FileName = pngFile;
using (Process exeProcess = Process.Start(PSI))
{
}
You can repeat this example with your own data as many times as you want to make many png files

Error upon sending and executing multiple test files

I am writing an application which launches a tester (.cmd), so I am passing in the tests that have been entered into a listbox. This method works perfectly fine if there is one test entered, but if there is 2 or more, it give me the error:
"An unhandled exception of type 'System.ComponentModel.Win32Exception'
occurred in System.dll
Additional information: The system cannot find the file specified"
The StartInfo.Filename and the currentTestFromListbox[i] both look correct in the debugger.
Anyone have any idea where I'm going wrong?
I apologize that my code is confusing--im just a beginner.
public void executeCommandFiles()
{
int i = 0;
int ii = 0;
int numberOfTests = listboxTestsToRun.Items.Count;
executeNextTest:
var CurrentTestFromListbox = listboxTestsToRun.Items.Cast<String>().ToArray();
string filenameMinusCMD = "error reassigning path value";
int fileExtPos = CurrentTestFromListbox[i].LastIndexOf(".");
if (fileExtPos >= 0)
{
filenameMinusCMD = CurrentTestFromListbox[i].Substring(0, fileExtPos);
}
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = #"pushd Y:\Tests\" + filenameMinusCMD + #"\" + CurrentTestFromListbox[i];
startInfo.WorkingDirectory = #"pushd Y:\Tests\" + filenameMinusCMD + #"\";
startInfo.FileName = CurrentTestFromListbox[i];
Process.Start(startInfo);
//Wait for program to load before selecting main tab
System.Threading.Thread.Sleep(10000);
//Select MainMenu tab by sending a left arrow keypress
SendKeys.Send("{LEFT}");
i++;
if (i < numberOfTests)
{
checkIfTestIsCurrentlyRunning:
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.Contains("nameOfProgramIAmTesting"))
{
System.Threading.Thread.Sleep(2000);
//if (ii > 150)
if (ii > 6) //test purposes only
{
MessageBox.Show("The current test (" + filenameMinusCMD + ") timed out at 5 minutes. The next test has been started.", "Test timed out",
MessageBoxButtons.OK,
MessageBoxIcon.Error,
MessageBoxDefaultButton.Button1);
}
ii++;
goto checkIfTestIsCurrentlyRunning;
}
goto executeNextTest;
}
}
}
}
Thanks!
-Joel
Here is your code re-factored. The sleeps/gotos were really bothering me. I couldn't really test it, but I think it should work the same. Let me know if it doesn't work or you have any questions.
This assumes your listbox has content like this in it:
testname.cmd
test2.cmd
test3.exe
lasttest.bat
Here is my attempt:
public void executeCommandFiles()
{
foreach (string test in listboxTestsToRun.Items)
{
//gets the directory name from given filename (filename without extension)
//assumes that only the last '.' is for the extension. test.1.cmd => test.1
string testName = test.Substring(0, test.LastIndexOf('.'));
//set up a FileInfo object so we can make sure the test exists gracefully.
FileInfo testFile = new FileInfo(#"Y:\Tests\" + testName + "\\" + test);
//check if it is a valid path
if (testFile.Exists)
{
ProcessStartInfo startInfo = new ProcessStartInfo(testFile.FullName);
//get the Process object so we can wait for it to finish.
Process currentTest = Process.Start(startInfo);
//wait 5 minutes then timeout (5m * 60s * 1000ms)
bool completed = currentTest.WaitForExit(300000);
if (!completed)
MessageBox.Show("test timed out");
//use this if you want to wait for the test to complete (indefinitely)
//currentTest.WaitForExit();
}
else
{
MessageBox.Show("Error: " + testFile.FullName + " was not found.");
}
}
}

How to create a RAM Disk with imdisk and C#?

I'm trying to create a RAM Directory via imdisk in C#. Since the cmd command is something like: imdisk -a -s 512M -m X: -p "/fs:ntfs /q /y"
I looked up how to process cmd commands with C# and found several hints regarding ProcessStartInfo(). This class works almost the way I intend it to, but since imdisk needs administrator priviliges I'm kinda stuck. Even though the code block is executed without exceptions, I don't see any new devices within the Windows Explorer.
try
{
string initializeDisk = "imdisk -a ";
string imdiskSize = "-s 1024M ";
string mountPoint = "-m "+ MountPoint + " ";
string formatHdd = "-p '/fs:ntfs /q /y' ";
SecureString password = new SecureString();
password.AppendChar('0');
password.AppendChar('8');
password.AppendChar('1');
password.AppendChar('5');
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.FileName = "cmd";
procStartInfo.Verb = "runas";
procStartInfo.UserName = "Admin";
procStartInfo.Password = password;
procStartInfo.Arguments = initializeDisk + imdiskSize + mountPoint + formatHdd;
Process.Start(procStartInfo);
catch (Exception objException)
{
Console.WriteLine(objException);
}
I hope someone can give me a little hint, right now I'm out of ideas.
Well I solved my problem in a different way. Somehow it seems that imdisk didn't format the new RamDisk the way it should and therefor no disk were created. As soon as I deleted the formatting option the disk is created and needs to be formatted. Therefore I started another process and used the cmd command "format Drive:"
For anyone who is interested, my solution is as follows:
class RamDisk
{
public const string MountPoint = "X:";
public void createRamDisk()
{
try
{
string initializeDisk = "imdisk -a ";
string imdiskSize = "-s 1024M ";
string mountPoint = "-m "+ MountPoint + " ";
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.FileName = "cmd";
procStartInfo.Arguments = "/C " + initializeDisk + imdiskSize + mountPoint;
Process.Start(procStartInfo);
formatRAMDisk();
}
catch (Exception objException)
{
Console.WriteLine("There was an Error, while trying to create a ramdisk! Do you have imdisk installed?");
Console.WriteLine(objException);
}
}
/**
* since the format option with imdisk doesn't seem to work
* use the fomat X: command via cmd
*
* as I would say in german:
* "Von hinten durch die Brust ins Auge"
* **/
private void formatRAMDisk(){
string cmdFormatHDD = "format " + MountPoint + "/Q /FS:NTFS";
SecureString password = new SecureString();
password.AppendChar('0');
password.AppendChar('8');
password.AppendChar('1');
password.AppendChar('5');
ProcessStartInfo formatRAMDiskProcess = new ProcessStartInfo();
formatRAMDiskProcess.UseShellExecute = false;
formatRAMDiskProcess.CreateNoWindow = true;
formatRAMDiskProcess.RedirectStandardInput = true;
formatRAMDiskProcess.FileName = "cmd";
formatRAMDiskProcess.Verb = "runas";
formatRAMDiskProcess.UserName = "Administrator";
formatRAMDiskProcess.Password = password;
formatRAMDiskProcess.Arguments = "/C " + cmdFormatHDD;
Process process = Process.Start(formatRAMDiskProcess);
sendCMDInput(process);
}
private void sendCMDInput(Process process)
{
StreamWriter inputWriter = process.StandardInput;
inputWriter.WriteLine("J");
inputWriter.Flush();
inputWriter.WriteLine("RAMDisk for valueable data");
inputWriter.Flush();
}
public string getMountPoint()
{
return MountPoint;
}
}
Doesn't cmd.exe need to have the /C command line option passed through to run a command passed through as an argument? May well be that cmd.exe is just ignoring what you're passing through in procStartInfo.Arguments because you haven't prepended "/C " onto the front of the Arguments.

How to uninstall Software using c# by calling Software UninstallString Listed in Registry file of that Software But the Process Is Not Working

I am developing a software that will list all the software install
in Computer
now i want to Uninstall it using my Program In C# by
calling the Uninstall Key of that software in
Registry Key
My Program Is
Like That But the Process Is Not Working
var UninstallDir = "MsiExec.exe /I{F98C2FAC-6DFB-43AB-8B99-8F6907589021}";
string _path = "";
string _args = "";
Process _Process = new Process();
if (UninstallDir != null && UninstallDir != "")
{
if (UninstallDir.StartsWith("rundll32.exe"))
{
_args = ConstructPath(UninstallDir);
_Process.StartInfo.FileName = Environment.SystemDirectory.ToString() + "\\explorer.exe";
_Process.StartInfo.Arguments = Environment.SystemDirectory.ToString() + "\\" + UninstallDir;
_Process.Start();
}
else if (UninstallDir.StartsWith("MsiExec.exe"))
{
_args = ConstructPath(UninstallDir);
_Process.StartInfo.FileName = Environment.SystemDirectory.ToString() + "\\cmd.exe";
_Process.StartInfo.Arguments = Environment.SystemDirectory.ToString() + "\\" + UninstallDir;
_Process.Start();
}
else
{
//string Path = ConstructPath(UninstallDir);
_path = ConstructPath(UninstallDir);
if (_path.Length > 0)
{
_Process.StartInfo.FileName = _path;
_Process.StartInfo.UseShellExecute = false;
_Process.Start();
}
}
Try this approach:
Process p = new Process();
p.StartInfo.FileName = "msiexec.exe";
p.StartInfo.Arguments = "/x {F98C2FAC-6DFB-43AB-8B99-8F6907589021}/qn";
p.Start();
Refer to this link: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/msiexec.mspx?mfr=true
HTH.
The problem with your misexec.exe code is that running cmd.exe someprogram.exe doesn't start the program because cmd.exe doesn't execute arguments passed to it. But, you can tell it to by using the /C switch as seen here. In your case this should work:
_Process.StartInfo.FileName = Environment.SystemDirectory.ToString() + "\\cmd.exe";
_Process.StartInfo.Arguments = "/C " + Environment.SystemDirectory.ToString() + "\\" + UninstallDir;
Where all I did was add /C (with a space after) to the beginning of the arguments. I don't know how to get your rundll32.exe code to work, however.
Your solution looks good, but keep a space before \qn:
p.StartInfo.Arguments = "/x {F98C2FAC-6DFB-43AB-8B99-8F6907589021} /qn";
Otherwise it wont work in silent mode.

Categories