2

I am Working in Visual Studio 2008 Winforms Application project in Windows 7 (32 bit).I am doing the project in C#. I have placed some buttons in a tab and added actions for that once it is clicked. While clicking the button am just running a .exe file in its action part. My problem is that, i opened a window by clicking one button(so the .exe file is running), now while am clicking the button again it is opening same window again irrespective of checking that it is open or not. I want to solve this issue,as when a window is opened it must not open again on another click on same button. How to solve this issue. ? Please help.... Thanks in advance..

yemans
  • 827
  • 3
  • 12
  • 16
  • Welcome on StackOverflow. Is it your own executable which you are running or someone else's executable? Have you tried anything? If yes, what have you tried? Do you need other buttons to be clickable while the exe is running or shall your whole application become unresponsive? – Thomas Weller Mar 12 '14 at 14:13
  • See http://stackoverflow.com/questions/3087841/how-can-i-make-a-single-instance-form-not-application, I recommend to use the Jon's answer – sallushan Mar 12 '14 at 14:16
  • @JBurnham: I think it's the window of the executable, not his own window, so it's more a "Does the process still run?" question. – Thomas Weller Mar 12 '14 at 14:19
  • @yemans could you try my answer? – Max Mar 12 '14 at 14:52

5 Answers5

0

You could check if the process is already running, when re-clicking the button:

private void btnStartExecutable_Click(object sender, EventArgs e)
{
   Process[] processName = Process.GetProcessesByName("InsertProcessNameHere");
   if (pname.Length == 0)
   {
       MessageBox.Show("Application isn't running yet.");
       //Start application here
       Process.Start("InsertProcessNameHere");
   }
   else
   {
       MessageBox.Show("Application is already running.");
       //Don't start application, since it has been started already
   }
}
Max
  • 11,885
  • 15
  • 70
  • 96
  • And how would the button enable once the process finished? – Thomas Weller Mar 12 '14 at 14:23
  • @Crono Could you reconsider my answer? – Max Mar 12 '14 at 14:48
  • @MaxMommersteeg if the process name is very specific and/or uncommon then this may do, yes, but this is still not something I would do. I give you +1 because that's still an helpful answer (I did not downvote btw). – Crono Mar 12 '14 at 15:11
0

The right answer here IMHO is that unless the two application shares a common resource or can talk to each other through some channel, there is no safe and efficient way to achieve what you want. Since the process is external, it could already be running before your calling app starts, or even while it's already running. You won't be able to tell if the process has been started from your app or not.

By the time I'm writing this your question does not yet state if you are in liberty to modify the external app you are calling. If you are however, using a Mutex would be a quick and easy way to solve your problem.

In your external app, whenever you want to make the other app aware of whatever condition you want (be it that the process is running or that a specific window is opened), have a Mutex instance created like this:

var mutex = new Threading.Mutex(true, "mutex unique identifier");

And in your calling app, try to create a Mutex instance with the same identifier:

bool alreadyExists;
var mutex = new Threading.Mutex(false, "mutex unique identifier", out alreadyExists);

Here the alreadyExists variable will tell you whether or not the external process is running or not. This is much safer than trying to identify it via its name, as other processes could have the same or a new version could be of a different name. Of course, the mutex identifier must be as unique as possible (like a Guid), otherwise you may encounter the same problem. ;)

Whenever you feel like the mutex must be released (at external app level), release it:

mutex.ReleaseMutex();

Note that if the process ends the mutex will be automatically released by the OS.

If the external app isn't a .NET based app, you can still create a mutex with Win32 API functions.

Crono
  • 9,769
  • 3
  • 40
  • 73
  • Why make it so complex? Process class comes with events that can be used here. – danish Mar 12 '14 at 15:55
  • @danish that won't help to determine whether the process itself is running or not. It could be already running by the time the calling app was started or it could also be executed diffently, like if the user runs it himself rather than clicking that specific button. – Crono Mar 12 '14 at 16:41
0

You can try this:

    bool processExited = true;
    private void button1_Click(object sender, EventArgs e)
    {
        if (processExited)
        {

            Process process = new Process();
            process.EnableRaisingEvents = true;
            process.Exited += MyProcessExited;
            process.StartInfo = new ProcessStartInfo();
            process.StartInfo.FileName = "notepad.exe";
            process.Start();
            processExited = false;
        }
        else
        {
            MessageBox.Show("Still running");
        }

    }

    void MyProcessExited(object sender, EventArgs e)
    {
        processExited = true;
    }
danish
  • 5,436
  • 2
  • 24
  • 28
  • This won't help you knowing if the process has already been started. – Crono Mar 12 '14 at 16:39
  • I don't see that condition in the question. – danish Mar 12 '14 at 16:47
  • It kinda goes without saying, don't you think? If the calling app was the only possible starting point for the external app, why would there even *be* an external app? – Crono Mar 12 '14 at 16:55
  • No it does not. I can think of lot of situations that may or may not be applicable to OP and will make it rather difficult to answer. What if OP is trying to run excel or word or notepad like thing? – danish Mar 12 '14 at 17:01
  • Assuming that the OP doesn't care that these apps could already be opened (which I doubt), then yes, this works. Although it may not be enough if, as the OP mentionned, what he needs is to know about a specific window being opened. – Crono Mar 12 '14 at 17:07
  • I would rather assume simplest of scenarios unless I am getting paid. :) – danish Mar 12 '14 at 17:08
0

Thanks for the support.. I got the answer like this..

1) Creating an event'Exit' for the process in function button click 2) Define a function for the exit event where you set a flag 3) Check the flag is set or not everytime while opening the process in the function button click

Event for Exit: 'P' is the name of process: p.Exited += new EventHandler(p_Exited);

p_Exited will be the function name where we will set the flag.

Thanks all...

yemans
  • 827
  • 3
  • 12
  • 16
  • You should either mark your own answer as correct, or someone else's. People are more likely to help you in the future if you have a higher percentage of questions marked as "answered". – Bradley Uffner Mar 13 '14 at 12:58
-2

If you know the name of the process that gets started or the path the .exe is run from you can use the Process class to check to see if it is currently running. http://msdn.microsoft.com/en-us/library/system.diagnostics.process(v=vs.110).aspx

Bradley Uffner
  • 16,146
  • 3
  • 39
  • 65
  • He is running an executable by himself, so he's already aware of the Process class. – Thomas Weller Mar 12 '14 at 14:25
  • It isn't entirely clear from the question what he wants to do if the target application is already running (started manually perhaps). There are static methods on Process that allow you to query the OS to determine this. It also allows you to hook events to find out when the application has exited. Using the Process class to start an application doesn't mean he understands the entire scope of what the class can do. – Bradley Uffner Mar 12 '14 at 14:52