Windowsモバイル:1つのアプリケーションインスタンス

問題



Windowsモバイルプロジェクト(Visual Studio 2008、.net cf 3.5、C#)で作業しているときに、アプリケーションの1つのインスタンスの起動を制御する際に問題が発生しました。 残念ながら、.net compact framework 3.5(およびそれ以前のバージョン)の作成者は、 System.Diagnostics.Process .GetProcessesByName()メソッドという名前でプロセスを検索する機能を有効にしませんでした。 マネージコードを使用して問題を解決する追加の方法は見つかりませんでした。



解決策



この問題は、アンマネージコードを使用していくつかの方法で解決できます。 グローバルプロセス同期オブジェクトは、ミューテックス、セマフォ、およびイベントのアシスタントとして機能します。 後者について説明しましょう。

まず、イベントの永続的な識別子を作成する必要があります(Visual Studioには組み込みのGUIDジェネレーターがあります:[ツール]-> [GUIDの作成])。

private static readonly Guid SingleInstanceGuid = new Guid"1DADFDD1-DDD1-4390-95B9-5852CFB39807" );




次に、アンマネージコードを使用します。

private const int ERROR_ALREADY_EXISTS = 183; //既存のイベントの場合に返されるエラーコード



[DllImport( "coredll.dll" 、SetLastError = true )]

private static extern IntPtr CreateEvent( IntPtr lpEventAttributes、 bool bManualReset、 bool bInitialState、 string lpName);



[DllImport( "coredll.dll" 、SetLastError = true )]

private static extern bool CloseHandle( IntPtr hObject);



[DllImport( "coredll.dll" 、SetLastError = true )]

private static extern IntPtr FindWindow( string className、 string wndName);




イベントを作成し、エラーコードを取得し、答えを返します。

public static bool IsSingleInstance(){

var path = Assembly .GetExecutingAssembly()。GetName()。CodeBase;

handle = CreateEvent( IntPtr .Zero、 falsefalse 、SingleInstanceGuid.ToString());

var error = Marshal.GetLastWin32Error();



//イベントが既に存在する場合、実行中のアプリケーションを見つけて0x8001コマンドを送信します。これにより、アプリケーションが再アクティブ化されます。

if (error == ERROR_ALREADY_EXISTS){

var hWnd = FindWindow( "#NETCF_AGL_PARK_" + path、 string .Empty);



if (hWnd!= IntPtr .Zero){

var msg = Message.Create(hWnd、0x8001、( IntPtr )0、( IntPtr )0);

MessageWindow.SendMessage( ref msg);

}



falseを 返し ます

}



trueを 返し ます

}




アプリケーションを閉じる前に、イベントを閉じます。

public static void CloseHandle(){

CloseHandle(ハンドル);

}




便宜上、このコードはすべて、SingleInstance.csなどのクラスに配置します。 実際には、program.csファイルで次のように適用されます。



if (!SingleInstance.IsSingleInstance()){

帰る

}

{

Application.Run( new Form1());

} catch (例外ex){

} 最後に {

SingleInstance.CloseHandle();

} *このソースコードは、 ソースコードハイライターで強調表示されています。




ミューテックスを使用するバリアントにも同様の考えがあります。

このソリューションが誰かに役立つことを願っています。



All Articles