41486


掲題の件、C#で同じWindows Formsのexeで特定の引数が同じ場合に2重起動を防止したいのですが  
可能でしょうか？

例) 「A.exe argA argB」を起動中に以下の要件を満たしたい。  
A.exe argC argD は、起動OK  
A.exe argA argE は、起動NG

引数は必ず指定されるものとします。引数が不足している場合は、起動エラーにします。  
arg[0]が文字列として完全一致した場合に、2重起動を抑止したいです。

具体的な、要件ですが、Windows Formsの画面をメニューから  
同じランチャ(A.exe）を使って、異なるForm画面を起動しようとしています。  
（A.exeが異なる引数で複数のプロセスとして起動することになります。）  
その際に、同じアプリコードの画面の場合に起動を抑止したいです。

何かアドバイス頂ければと思います。  
よろしくお願いいたします。


CC BY-SA 3.0
2018-02-05T08:06:12.917
41484
2018-02-05T11:08:12.287
2018-02-05T11:00:35.450
9228
9228
question
c# winforms
C# Windows Formsで同じプロセス名で特定の引数が同じ場合の2重起動防止方法は？


他プロセスのコマンドライン引数はWMIで取得できますので、起動時に排他をかけつつ値を検証すればよいのでは。

[code]

    [STAThread]
    private static void Main(string[] args)
    {
        var cp = Process.GetCurrentProcess();
        Console.WriteLine($"PID:{cp.Id}");
        for (var i = 0; i < args.Length; i++)
        {
            Console.WriteLine($" - {i}: {args[i]}");
        }
    
        var mutex = new Mutex(false, typeof(Program).FullName);
    
        try
        {
            Console.WriteLine("Entering Mutex");
            mutex.WaitOne();
    
            var pn = cp.ProcessName + ".exe";
    
            using (var mc = new ManagementClass("Win32_Process"))
            {
                foreach (var op in mc.GetInstances())
                {
                    if (pn.Equals(op["Name"] as string, StringComparison.InvariantCultureIgnoreCase))
                    {
                        var pid = Convert.ToInt32(op["ProcessId"]);
    
                        if (pid == cp.Id)
                        {
                            continue;
                        }
    
                        var cmd = op["CommandLine"] as string;
    
                        // TODO:コマンドライン引数は""でエスケープできるのできちんと解析する必要がある
                        var otherArgs = cmd.Split(' ')
                                            // 先頭は実行ファイルのため飛ばす
                                            .Skip(1)
                                            .ToArray();
    
                        Console.WriteLine($"PID:{pid}");
                        for (var i = 0; i < otherArgs.Length; i++)
                        {
                            Console.WriteLine($" - {i}: {otherArgs[i]}");
                        }
    
                        // 引数が被っていたら終了
                        if (args.Intersect(otherArgs).Any())
                        {
                            Console.WriteLine("Already exists");
                            return;
                        }
                    }
                }
            };
        }
        finally
        {
            mutex.ReleaseMutex();
            Console.WriteLine("Exit Mutex");
        }
    
        // TODO: 実際の起動処理を入れる。
        // Application.EnableVisualStyles();
        // Application.SetCompatibleTextRenderingDefault(false);
        // Application.Run(new Form1());
        Console.WriteLine("Hit any key to exit...");
        Console.ReadKey();
    }
    
[/code]


CC BY-SA 3.0
2018-02-05T11:08:12.287
41486
2018-02-05T11:08:12.287
5750
41484
answer