I have a application which will open a two microsoft ppsx file one after another. for that i have used process object to run the files. mention bellow
Process process = Process.Start(#"E:\test\test.ppsx");
I need to run the files in such a way that after finishing the first file ,second file should run automatically. can some one suggest me how can achieve that.
You can use WaitForExit method to wait to end process (Something like this):
var process1 = Process.Start(...);
process1.WaitForExit();
var process2 = Process.Start(...);
or subscribe into a Process.Exited event and execute another process after the first one. Check this for your reference.
You can use Process.WaitForExit method.
Instructs the Process component to wait indefinitely for the
associated process to exit.
Also check Process.Exited event.
Occurs when a process exits.
Process process = Process.Start(#"E:\test\test.ppsx");
process.WaitForExit();
Use Process.WaitForExit()
class Program
{
static void Main(string[] args)
{
Task.Run(() =>
{
Process.Start(#"c:\temp\presentation1.pptx").WaitForExit();
}).ContinueWith(o =>
{
Process.Start(#"c:\temp\presentation2.pptx").WaitForExit();
});
Console.ReadKey();
}
}
You should get all the ppsx files from the test directory in the E drive in an array and process on the array of ppsx files according to your requirements.
string[] files = Directory.GetFiles("your path");
loop through the array and pass each file path to the Process constructor and as lexeRoy said you can WaitForExit.
Related
Many examples and MSDN are using a new Process to get the exitcode, however, creat a new variable looks not so grace.So, I tried this
Process.Start("Application.exe", "parameter").WaitForExit().ExitCode
aimed to get the exitcode in one line but failed.
And is there any solution of this writing?
It doesn't work like that because WaitForExit() returns a bool, which doesn't have an ExitCode property. If you want this behavior on one line, you'll have to implement it yourself in a method and call it.
public int RunAndGetCode(string executable, string parameter)
{
var process = Process.Start(executable, parameter).WaitForExit();
return process.ExitCode;
}
// then later
var code = RunAndGetCode("Application.exe", "parameter");
So... That's not quite how Process works. You could write a wrapper class that allows you to do it in one one line, or using a using block, but when you have to wait for any process, that means you're locking up your own process while waiting for it. In Windows that is terrible practice.
The way it's designed in C#, it allows your own process to do other work while the process you called has returned. (Wrote this on mobile device; apologies for errors)
So, in short, no, but I see nothing wrong with this:
Process p = new Process();
P.Start();
While(!p.WaitForExit()) {
//do work while you wait for the calling process to return
}
var exitCode = p.ExitCode
So for my recent project I need to put the content generated by A console app in a WPF textBox.
The point is the app generates the text file (test.txt) only after process completion which can take some time.
Here's the code for the same:
foreach (var website in lst) //list can have several entries.
{
var args = "-v -all -text test.txt n" + website.ToString() + " 443";
Process.Start(#"C:\TestSSLServer.exe", args);
Task.Factory.StartNew(() =>
{
MyValue = System.IO.File.ReadAllText(#"C:\test.txt");
});
}
How do I make sure that the text box is only populated when the console app TestSSLServer quits?
Edit: Process.WaitForExit(); does not work. I tried it :( Still throws file not found exception.
Thanks.
You can use Process.WaitForExit() to block until the process exits.
Process p = Process.Start(#"C:\TestSSLServer.exe", args);
p.WaitForExit();
I would note that this will block whatever thread it's run on. If you want to be notified when the process exits instead use the Process.Exited event.
You need to store the process in a variable of type Process. Then you can set its EnableRaisingEvents flag to true and subscribe to the event signaling that the process has ended. Your handler should be the function which populates the text box.
Sample code is available on MSDN.
https://msdn.microsoft.com/en-us/library/system.diagnostics.process.exited(v=vs.110).aspx
I have a process A that reads in some data produced by some other process B. The data is 'exchanged' via the file system. To ensure that the file exists, process A currently checks for the file's existence like this:
while (!File.Exists(FileLocation))
{
Thread.Sleep(100);
}
This only seems to work 99 percent of the time. The other 1 percent of the time, process A establishes that the file exists but process B has not written everything yet (i.e. some data is missing).
Is there another simpler way to make the above situation more bullet proofed? Thanks.
Is there another simpler way to make the above situation more bullet proofed?
You could use a Mutex for reliable inter-process synchronization. Another possibility is to use a FileSystemWatcher.
After determining that the file exists, you can try opening the file for exclusive access, which will fail if another process still has the file open:
try
{
File.Open("foo",FileMode.Open,FileAccess.Read,FileShare.None);
}
catch(IOException ex)
{
// go back to
}
Given that you say that you can change both processes' code, you can use an EventWaitHandle to communicate between the processes.
In your program that creates the file, in the Main() method you can create an EventWaitHandle and keep it around until the end of the program. You'll need to pass the EventWaitHandle object around in your program so that it is available to the bit of code that creates the file (or provide some method that the file-creating code can call to set the event).
using (EventWaitHandle readySignaller = new EventWaitHandle(false, EventResetMode.ManualReset, "MySignalName"))
{
// Rest of program goes here...
// When your program creates the file, do this:
readySignaller.Set();
}
Then have some code like this in the program that's waiting for the file:
// Returns true if the wait was successful.
// Once this has returned true, it will return false until the file is created again.
public static bool WaitForFileToBeCreated(int timeoutMilliseconds) // Pass Timeout.Infinite to wait infinitely.
{
using (EventWaitHandle readySignaller = new EventWaitHandle(false, EventResetMode.ManualReset, "MySignalName"))
{
bool result = readySignaller.WaitOne(timeoutMilliseconds);
if (result)
{
readySignaller.Reset();
}
return result;
}
}
NOTE: If we successfully wait note that I am resetting the signal and it will remain reset until the other process sets it again. You can handle the logic differently if you need to; this is just an example.
Essentially what we are (logically) doing here is sharing a bool between two processes. You have to be careful about the order in which you set and reset that shared bool.
Try the FileSystemWatcher.
Listens to the file system change notifications and raises events when
a directory, or file in a directory, changes.
Is there any alternative other than Process to execute built-in shell commands in C#? Currently I am using Process class to run those commands. But in the current scenario I want to run more than 200 such commands in parallel. So spawning more than 200 processes is not a good idea. Is there any other alternative?
"Running a dos command" is the equivalent to "Creating a process and running it" so even if there is an other api, there will still be 200 processes (which, by the way, is nothing to worry about unless you're on a really, really tiny system)
You could but, shouldn't do
using Microsoft.VisualBasic;
Interaction.Shell(...);
Note: You would have to add a reference to the the VisualBasic assembly.
This is a direct answer to your question but, not somthing you should do.
As Max Keller pointed out, System.Diagnostics.Process always starts a new system process.
If have to start processes/operations for more than just some seconds, I would prefer to save all commands in a temp file and execute this with System.Diagnostics.Process rather than ever single operation.
// Get a temp file
string tempFilepath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "MyBatchFile.bat");
// Ensure the file dont exists yet
if (System.IO.File.Exists(tempFilepath)) {
System.IO.File.Delete(tempFilepath);
}
// Create some operations
string[] batchOperations = new string[]{
"START netstat -a",
"START systeminfo"
};
// Write the temp file
System.IO.File.WriteAllLines(tempFilepath, batchOperations);
// Create process
Process myProcess = new Process();
try {
// Full filepath to the temp file
myProcess.StartInfo.FileName = tempFilepath;
// Execute it
myProcess.Start();
// This code assumes the process you are starting will terminate itself!
} catch (Exception ex) {
// Output any error to the console
Console.WriteLine(ex.Message);
}
// Remove the temp file
System.IO.File.Delete(tempFilepath);
I just wanna ask your opinion/suggestion on how to 'terminate' a running application/process is C#
Right now, I do have the following codes:
Process myProcess;
private void btnOpen_Click(object sender, RoutedEventArgs e)
{
DirectoryInfo di = new DirectoryInfo(System.Environment.GetFolderPath(Environment.SpecialFolder.Programs));
myProcess = Process.Start(di + #"\Wosk\Wosk.appref-ms"); // opening a file coming for Startup Menu
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
myProcess.Kill(); // not working - Cannot process request because the process has exited
}
I also tried myProcess.Close(); but nothing's happening.
You should have a look at
Process.HasExited Property
A process can terminate independently
of your code. If you started the
process using this component, the
system updates the value of HasExited
automatically, even if the associated
process exits independently.
Based on your comment it looks like the Process instance has already exited when you hit the close button. This can happen at any time and it's something you need to guard against. The easiest way is to simply catch the exception that results from calling Kill on an already exited process.
try {
myProcess.Kill();
} catch ( InvalidOperationException ) {
// Process is already finished so nothing to do
}
You are starting a program that was installed with ClickOnce. The .appref-ms is executed by a helper program, rundll32.exe, that starts the process and quickly exits. To terminate the started process, you'll need to find the actual running .exe with Process.GetProcessesByName() and use the Kill method.
We can't tell you what the process name is, that's contained in the .appref-ms file. But it is easy for you to see with TaskMgr.exe.
Process[] islemler = Process.GetProcessesByName("osk");
foreach (Process islem in islemler)
islem.Kill();
First please replace:
di + #"\Wosk\Wosk.appref-ms"
with:
Path.Combine(di.FullName, #"Wosk\Wosk.appref-ms")
Now to the point: I don't know what Wosk.appref-ms is or how this process is started. If this is a file it will be opened with the default program associated with this file extension. The problem could be related to the fact that the process you start only starts another process and terminates immediately. That's why when you try to kill it it says that it has already exited, but the actual process it spawned is still running. In this case you will have to enumerate through the running processes with Process.GetProcesses(), find the process and stop it.