开发者

How to find whether a given application is single instance or not?

I am looking for an efficient way to find whether a given application (say app.exe) is single instance or not? I thought of these following sols:

  1. Do CreateProcess() twice and check whether there are two or more instance running of that application? If no, it is single instance application. But, this is not efficient.
  2. Do CreateProcess() and wait for 1-2 sec. If this instance is killed (because there is already an instance running for it), it will be single instance app.

But I am not convinced with both above sol. Is there any other efficient way of doing that in windows?

Please note that I don't to kill or make any modifications to an already running (if any) ins开发者_Go百科tance of that application.


Think about it the other way: When you write a program, how do you specify whether it is single-instance or multiple-instance? Is there a way that some other program can get that information out of your program without running it? (Once you answer this question, then you have the answer to your question.)

This problem is not solvable in general because single-instance/multiple-instance-ness is determined at runtime and can be based on runtime conditions. For example, some applications are "sometimes multiple instance, sometimes single": If you run the application to open document X, and then document Y, you will get two instances. But if you open document X, and then document X again, the two instances will fold into one. Other applications may have a configuration switch that lets you select whether they are single-instance or multiple-instance. Or maybe they decide to flip a coin and decide to be single-instance if tails and multiple-instance if heads.


The best way is via using synchronization object called Mutex (Mutually exclusive). You may google it. I think the following code may help to.

//---------------------------------------------------------------------------
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    try
    {
        HANDLE hMutex=OpenMutex(MUTEX_ALL_ACCESS,0,"SIns");
        if (!hMutex) {
            //Mutex doesn’t exist. This is the first instance so create the mutex.
            //in this case app name is SIns (Single Instance)
            hMutex=CreateMutex(0,0,"SIns");
            Application->Initialize();
            Application->MainFormOnTaskBar = true;
            Application->CreateForm(__classid(TfMain), &fMain);
            Application->Run();
            ReleaseMutex(hMutex);
        }
        else{
            //This is not single. The prev instance is already running 
            //so informing about it 
            //remember that if it finds prev instance we're activating it here
            //you may do whatsoever here ...... e.g. you may kill process or stuff like this:)
            ShowMessage("The program is already running. Switching to ...");
            HWND hWnd=FindWindow(0,"SIns");
            SetForegroundWindow(hWnd);
        }

    }
    catch (Exception &exception)
    {
        Application->ShowException(&exception);
    }
    catch (...)
    {
        try
        {
            throw Exception("");
        }
        catch (Exception &exception)
        {
            Application->ShowException(&exception);
        }
    }
    return 0;
}
//---------------------------------------------------------------------------


There is no way to do this at all. What happens if the application checks a mutex then makes a messagebox to tell the user an instance is already running and only when the user dismisses it does it kill the application? There are many different ways to ensure mutual exclusion via some shared resource, mutex, shared file, even maybe setting some registry key, the methods are unlimited.


The usual solution is to use some sort of a locking file. Under traditional Unix, for example, the application will start by creating a file (which will succeed even if the file exists), then try to create a link to it (an atomic action); if that fails, the application will immediately kill itself. Under Windows, the share mode of CreateFile can be used to the same effect: open a file with share mode 0, and if that fails, quit. (The Unix solution will leave the lock if the process crashes, requiring it to be cleaned up manually. The Windows solution will remove the lock if the system crashes.)


you may use mutexes... I do such check with following code:

bool insureApplicationUniqueness(HANDLE& mutexHandle)
{
    mutexHandle=CreateMutexW(NULL,true,UNIQUE_INSTANCE_MUTEX_NAME);
    if( mutexHandle&&(ERROR_ALREADY_EXISTS==GetLastError()))
    {
        CloseHandle(mutexHandle);
        return false;
    }
    return true;
}

but this is for application which source code is yours and which checks is another instance of itself running.


The problem with the notion is that in common environments, there is no explicit static data that determines whether an application is single-instance. You only have behavior to go on, but you cannot fully test behavior.

What if you have an app that is multi-instance, but will fail to open a file that's already open? If you test it twice with the same, valid filename, it would create only a single process, but any other command line argument would cause two processes to exist. Is this a single-instance program?

You could even argue that "single instance" isn't a well-defined catageory of programs for this reason.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜