4

C++ アプリケーションのインスタンスが 1 つだけ実行されていることを確認する必要があります。

Win API を使用する方法

  1. 現在のアプリケーションに関する情報を取得する GetCurrentProcess()アプリケーションの HANDLE が表示されます。それに関する情報を取得するにはどうすればよいですか

  2. ユーザーの実行中のすべてのプロセスのリストを取得しますか? EnumProcesses()リストを提供しますが、事前に割り当てられたバッファーが必要なようです。現在実行中のプロセスの数を確認するにはどうすればよいですか?

  3. サーバーのexe名を実行中のプロセスと比較する必要があり、複数見つかった場合はエラーを発生させます

注:ブースト ライブラリを使用することはできませんmutex。同様の投稿で見られる を使用することに興味はありません。

4

3 に答える 3

10

このCreateMutex関数を使用して、システム全体の名前付きミューテックスを作成し、プロセスが実行されているかどうかを示すことができます。ERROR_ALREADY_EXISTSプロセスがすでに実行されている場合は、次のように返されます。

 (void)::CreateMutex( NULL,
                      TRUE,
                      TEXT( "My_Special_Invokation_Test_Mutex" ) );
 switch ( ::GetLastError() ) {
     case ERROR_SUCCESS:
         // Process was not running already
         break;
     case ERROR_ALREADY_EXISTS:
         // Process is running already
         break;
     default:
         // Error occured, not sure whether process is running already.
         break;
 }

ミューテックスを使用しないと主張する場合は、CreateFile代わりに関数を使用できます。dwShareMode排他的アクセス セマンティクスを取得するCREATE_NEWためのフィールド、dwCreationDispositionフィールド (まだ存在しない場合にのみファイルを作成するため)、およびプロセスが終了するとファイルが削除されるようにFILE_FLAG_DELETE_ON_CLOSEするためのdwFlagsAndAttributes引数には、必ずゼロを渡してください。このようなもの:

LPCTSTR lockFileName = ...;
(void)::CreateFile( lockFileName,
                    GENERIC_READ,
                    0,
                    NULL,
                    CREATE_NEW,
                    FILE_FLAG_DELETE_ON_CLOSE,
                    NULL );
switch ( ::GetLastError() ) {
     case ERROR_SUCCESS:
         // Process was not running already
         break;
     case ERROR_FILE_EXISTS:
         // Process is running already
         break;
     default:
         // Error occured, not sure whether process is running already.
         break;
}

一時ファイルを安全に処理する方法については、一時ファイルの生成と使用に関するベスト プラクティスに関するこの記事を参照してください。

簡単に言うと、タスクにロック ファイルを使用することは確かに可能ですが、正しく行うのは難しいと思います。

于 2013-08-12T10:01:38.450 に答える
4

Nawazの回答の更新版:-

Handle mutex = CreateMutex (0, 0, "SomeUniqueName");

switch (GetLastError ())
{
case ERROR_ALREADY_EXISTS:
  // app already running
  break;

case ERROR_SUCCESS:
  // first instance
  break;

default:
  // who knows what happened!
  break;
}

これにはセキュリティ上の問題があります。悪意のあるアプリケーションが、アプリの起動前に「SomeUniqueName」というミューテックスを作成し、アプリの実行を妨げる可能性があります。これに対抗するために、一定のシステム パラメータ (MAC アドレスなど) のハッシュに基づいてミューテックスに名前を付けることができます。MSDNのドキュメントには、単一インスタンス アプリケーションについて次のように記載されています。

名前付きミューテックスを使用してアプリケーションを 1 つのインスタンスに制限している場合、悪意のあるユーザーがこのミューテックスを作成する前に作成し、アプリケーションの起動を妨げる可能性があります。このような状況を防ぐには、ランダムな名前のミューテックスを作成し、許可されたユーザーのみが取得できるように名前を保存します。または、この目的でファイルを使用することもできます。アプリケーションをユーザーごとに 1 つのインスタンスに制限するには、ユーザーのプロファイル ディレクトリにロックされたファイルを作成します。

于 2013-08-12T10:09:55.770 に答える