同一のプログラムが同時に起動すると、仕様上またはユーザビリティで問題が発生する場合があります。そのような場合にはアプリケーションが起動されたときに既に同じプログラムが起動していないか調べ、既にあれば何もせずに終了するなどして二重起動しないようにします。
単純にそのような機能を持つAPIは存在しないため、通常はプロセスを超えて使用できる同期オブジェクト、名前付ミューテックスを使用し、同じ名前のミューテックスが既に他のプロセスで使用されている場合は二重起動状態であると判断して終了などの処理をし、そうでない場合は、ミューテックスを作成した上で、本来の処理を続けるということで、目的を実現します。
ミューテックスの作成にはCreateMutexAPIを使用します。ミューテックスは無名でも作成できますが、今回の場合名前をキーにして既に存在するか調べますので、必ず名前を指定します。名前には'\'以外の任意の文字が使用できます。名前は他のアプリケーションと重ならないようにユニークなものにしなければなりません。EXE名とか、アプリケーション名を入れるのが良いでしょう。
また、WindowsXP以降のOSでは同時に2人以上のユーザがログイン状態になることが出来ますが、そのユーザー境界を越えてロックをしたい場合は、名前の前に、"Global\"をつけます。ただし、XP以前のOSの場合はつけてはなりません。この機能を使用する場合はOSのバージョンを判定して動作を分ける必要があります。
以下は、サンプルです。
HANDLE AppExecutableLock(LPCTSTR lpszMutexName)
{
HANDLE hMutex = CreateMutex(NULL, FALSE, lpszMutexName);
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
/* mutex already exists - application already exists */
/* close opened */
CloseHandle( hMutex );
hMutex = NULL;
}
return hMutex;
}
void AppExecutableUnlock(HANDLE hLock)
{
CloseHandle( hLock );
}
int MainFunc() {
/* lock application */
HANDLE hLock = AppExecutableLock("ApplicationLock:SampleApp");
if (hLock == NULL) {
return 1;
}
/* application work */
...
...
...
/* unlock */
AppExecutableUnlock(hLock);
return 0;
}