Malte
Malte

Reputation: 40

C# Detect if the same Executable is running and wait untill its closed

I have a Webapplication for News and also some Guides.

In the backend you have the function that you can upload multiple images with no limit, cause of pagination.

The Controller runs after the image was successfully added to the entry an ImageOptimizer Task for JPEG and for PNG.

I made a big stress test today and well my memory was at 100% usage because the processes were running all at the same time.

My question is: Is it possible to let the ProcessStart wait until the same executable ended? That would help a lot :-)

The Code for starte the task is pasted below. So I use simple the ProccessStart Cls in C#.

    public static string Do(string path, bool clientMode = false)
    {
        /** I want to do something like this:**/
        while(ThisExecutableIsAllreadyRunning);

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.AppendFormat("Optimizing \"{0}\"", path).AppendLine();
        long length = new FileInfo(path).Length;
        stringBuilder.AppendFormat("Size before: {0}", length).AppendLine();
        string text = "~/Executables/optipng.exe";
        if (clientMode)
        {
            if (String.IsNullOrEmpty(ClientModeExecutablePath))
                throw new Exception("Client Mode for IMG Optim required ClientModeExecutablePath to be set");

            text = ClientModeExecutablePath;
        }
        else
            text = HttpContext.Current.Server.MapPath(text);
        Process process = Process.Start(text, "-strip all " + path);
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.CreateNoWindow = false;
        process.Start();
        while (!process.StandardOutput.EndOfStream)
        {
            string value = process.StandardOutput.ReadLine();
            stringBuilder.AppendLine(value);
        }
        length = new FileInfo(path).Length;
        stringBuilder.AppendFormat("Size After: {0}", length).AppendLine();
        stringBuilder.AppendLine("Done...");
        return stringBuilder.ToString();
    }

Upvotes: 0

Views: 789

Answers (2)

ziddarth
ziddarth

Reputation: 1916

Here's how you can check if a particular exe application is already running due to some other thread or process:

using System.Diagnostics;

//get all currently running applications
var allProcesses = Process.GetProcesses().ToList();
//filter out the processes that don't match the exe you're trying to launch
foreach(var process in allProcesses.Where(p => p.Modules[0].FileName.ToLower().EndsWith(ClientModeExecutablePath.ToLower())))
{
    try
    {           
        Console.WriteLine("Process: {0} ID: {1}, file:{2}", process.ProcessName, process.Id, process.Modules[0].FileName);
        //wait for the running process to complete
        process.WaitForExit();
    }
    catch (Exception ex)
    {
        Console.WriteLine (ex);
    }

   //now launch your process
   //two threads could still launch the process at the same time after checking for any running processes

}

Upvotes: 1

user585968
user585968

Reputation:

Is it possible to let the ProcessStart wait untill the same executable ended?

Certainly. If I have understood you correctly you want to wait for the process to exit until continuing. Try this code:

Process process = Process.Start(text, "-strip all " + path);
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = false;
process.Start();
while (!process.StandardOutput.EndOfStream)
{
     string value = process.StandardOutput.ReadLine();
     stringBuilder.AppendLine(value);
}
process.WaitForExit();  // <-------- WAIT HERE

MSDN:

Instructs the Process component to wait indefinitely for the associated process to exit. WaitForExit() makes the current thread wait until the associated process terminates. It should be called after all other methods are called on the process. To avoid blocking the current thread, use the Exited event.

Concurrency

It's hard to tell if your Do() method is being called concurrently or not. If so you may want to protect it with some form of lock() or critical section to ensure only one process is spawned at a time. This places the guard in the instigator.

Alternatively you could create a named mutex in the .EXE. If it was found that the mutex previously exited you should immediately exit. This places the guard in the action.

Good luck!

Tell me more

Upvotes: 1

Related Questions