Compact Framework+C#で二重起動防止

まぁ、わざわざ載せておくほどでもないんですけど…自分用メモ。

Windows CE上のC#アプリケーションで二重起動を防止したかった。ググってみた、例によってWindowsでのページが引っかかる。例えば以下のページ…非常に親切に書かれてる。もちろん、WindowsというかCompactじゃない.NET Frameworkならコレでバッチリ ;)

でも、Compact Frameworkでは…上記ページの最初のアプローチ「現在起動しているプロセスを調べる方法」では、System.Diagnostics.ProcessクラスにGetProcessesByNameメソッドがない :arrow: ついでに言うと、ProcessNameプロパティもない :roll:

仕方ないので、上記ページの次のアプローチ「Mutexを使用する方法」を試す。Mutexを使う方法は以下のページのコードの方が良いと思ったのでコチラを試す(基本は同じですけど…ReleaseMutexとかチャンとしてたので)。

一応、先にCompact Frameworkでクラスやメソッドがあることを確認(習慣になりつつあります) :arrow: 大丈夫みたい。じゃぁ、コンパイル………ありゃエラー :shock: どこで…ぎゃあ~Mutexのコンストラクタに2引数のものがない。

うぐぁ~コンストラクタの引数まで確認してなかったよ :roll:

仕方ないので、ググってみるとみなさん同じようなこと(2引数のコンストラクタがないと)を書いている。結局、P/InvokeでCreateMutexを使えと :cry:

と言うことで、Compact Framework+VB.NET版は以下のページで見つけたけど…C#版がなかったのでコードをペタっと貼っておく。

    using HANDLE = System.IntPtr;
 
    static class Program
    {
        [MTAThread]
        static void Main()
        {
            HANDLE hMutex = CreateMutex(IntPtr.Zero, false, Assembly.GetExecutingAssembly().GetName().Name);
            if (GetLastError() != ERROR_ALREADY_EXISTS)
            {
                Application.Run(new Form1());
            }
            else
            {
                MessageBox.Show("アプリケーションは既に起動しています。");
            }
            ReleaseMutex(hMutex);
            CloseHandle(hMutex);
        }
 
        private const int ERROR_ALREADY_EXISTS = 183;
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern HANDLE CreateMutex(IntPtr lpMutexAttributes, bool bInitiaOwner, string lpName);
        [DllImport("coredll.dll")]
        private static extern int GetLastError();
        [DllImport("coredll.dll")]
        private static extern bool ReleaseMutex(HANDLE hMutex);
        [DllImport("coredll.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(HANDLE hObject);
    }

適当な部分はよしなに ;)

ReleaseMutexやCloseMutexは引数がIntPtr.Zeroでも問題ないようなので常に呼び出してます。

GotDotNetにCompact Frameworkでの二重起動防止のサンプルが在ったようなので…そちらの方が良い可能性が高いです。でも、見つけられなかったのよね :arrow:

しかし、Microsoftさま…Mutexに2引数(名前付きMutex)のコンストラクタを実装するのは、そんなに大変なのでしょうか :?: それともコレを実装するとCompact Frameworkが肥大化するのでしょうか :?: まぁ、何でも要求に沿って入れていけばCompactじゃなくなるので、取捨選択は重要だと思いますけど…。

小一時間問い詰めたい選択が多すぎです

Be Sociable, Share!

TrackBack URL :

No comments yet. Be the first.

Leave a reply