dotnet 判斷特定進程存在方法

  • 2019 年 10 月 8 日
  • 筆記

本文告訴大家幾個方法判斷特定的進程是否存在,同時對比這些方法的性能

使用鎖判斷

在 C# 中判斷一個進程存在的方法,如果這個進程是自己創建的,可以通過 Mutex 的方法,通過創建一個鎖,然後在其他進程判斷這個鎖是否存在。這使用到內核的方法,性能不錯

假設需要判斷進程 HacurbonefeciloQicejewarrerai 是否存在,而這個進程是自己寫的進程,那麼可以在這個進程的主函數創建一個鎖請看程式碼

    class Program      {          static void Main(string[] args)          {              var mutex = new Mutex(true, Const.Lock, out var createdNew);                if (!createdNew)              {                  Console.WriteLine("已經有進程啟動");              }                Console.ReadKey();                mutex.Dispose();          }      }        public static class Const      {          public const string Lock = "5742D257-CCCC-4F7A-2191-6362609C452D";      }

在另一個進程可以使用下面方法判斷進程是否已經存在

        public bool FindExistByMutex()          {              return Mutex.TryOpenExisting(Const.Lock, out var result);          }

在使用 Mutex 如果沒有傳入 Name 那麼將會在一個進程內,使用相同對象的鎖,做到同步。如果給了命名,將會調用內核,在所有進程同步

使用鎖判斷進程存在將需要小心這些問題 .NET 中使用 Mutex 進行跨越進程邊界的同步 – walterlv

使用進程名判斷

另一個方法是通過進程名判斷,這樣判斷的進程就不需要是自己寫的進程,通過進程名判斷是獲取對應進程名的進程,通過判斷返回數組元素,請看程式碼

        public bool FindExistByProcessName()          {              var name = "HacurbonefeciloQicejewarrerai";              return Process.GetProcessesByName(name).Length > 0;          }

上面程式碼的 name 傳入需要判斷的進程

在使用進程名判斷的時候,可選的方法還有通過 Process.GetProcesses() 然後判斷裡面的進程名,但是使用上面方法的性能是最高的

使用 Process 判斷進程是否存在的方法性能請看 .NET 中 GetProcess 相關方法的性能 – walterlv

現在已經告訴大家兩個方法判斷進程是否存在,通過內核方式判斷的性能比較快,請看下面性能

兩個方法性能

使用標準性能測試 測試了兩個方法的性能,可以看到使用內核的方式的性能很快

BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362  Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores    [Host]     : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.8.4010.0    DefaultJob : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.8.4010.0

Method

Mean

Error

StdDev

FindExistByProcessName

6,955.411 us

197.9235 us

580.4753 us

FindNotExistByProcessName

6,552.935 us

198.3320 us

271.4790 us

FindExistByMutex

3.032 us

0.0908 us

0.2649 us

FindNotExistByMutex

2.064 us

0.0412 us

0.0521 us

測試程式碼請看下面

    public class Program      {          static void Main(string[] args)          {              BenchmarkRunner.Run<Program>();          }            [Benchmark]          public bool FindExistByProcessName()          {              var name = "HacurbonefeciloQicejewarrerai";              return Process.GetProcessesByName(name).Length > 0;          }            [Benchmark]          public bool FindNotExistByProcessName()          {              return Process.GetProcessesByName("不存在的進程").Length > 0;          }            [Benchmark]          public bool FindExistByMutex()          {              return Mutex.TryOpenExisting(Const.Lock, out var result);          }            [Benchmark]          public bool FindNotExistByMutex()          {              return Mutex.TryOpenExisting("不存在的進程", out var result);          }      }

在運行測試程式碼之前先使用下面程式碼測試判斷進程存在

        static void Main(string[] args)          {              Process.Start("HacurbonefeciloQicejewarrerai.exe");                var program = new Program();                Console.WriteLine($"FindExistByProcessName={program.FindExistByProcessName()}");              Console.WriteLine($"FindNotExistByProcessName={program.FindNotExistByProcessName()}");              Console.WriteLine($"FindExistByMutex={program.FindExistByMutex()}");              Console.WriteLine($"FindNotExistByMutex={program.FindNotExistByMutex()}");          }

程式碼放在 github 歡迎下載