功能:可防止exe更名、挪動位置再運行的問題
實現思路:
在Main()方法開始時遍歷所有進程,獲取每個進程的程序集GUID和PID,若發現有跟自己GUID相同且PID不同的進程,就勒令自身退出。
注:
1、采用GUID是為了盡可能保證判定的可靠性,采用進程名太不靠譜。因為程序集GUID是建立項目時就生成的,不隨版本、內容的變化而變化,所以除非人為改動,否則同一項目編譯若干次都還是那個GUID,用來判斷程序集身份再適合不過。題外,市面上常見的互斥體方法,互斥名也建議采用GUID;
2、之所以要加上進程ID的判斷,是因為遍歷的進程中已經包含自身進程,所以必須排除自身;
3、經嘗試似乎只有.Net程序集才能獲取到GUID(有點廢話~),但這樣已經足夠
4、第一次在cnblogs寫博,希望各位前輩多多指教~少扔磚頭
using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; namespace TestCallAPIRefreshPolicy { static class Program { [STAThread] static void Main() { Guid ownGUID = new Guid(((GuidAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(GuidAttribute))).Value); int ownPID = Process.GetCurrentProcess().Id; foreach (Process p in Process.GetProcesses()) { try { //這兒之所以用Assembly.Load(byte[])獲得程序集是因為該方法不會鎖住文件 Guid proGUID = new Guid(((GuidAttribute)Attribute.GetCustomAttribute(Assembly.Load(File.ReadAllBytes(p.MainModule.FileName)), typeof(GuidAttribute))).Value); if (ownGUID == proGUID && ownPID != p.Id) { MessageBox.Show("程序已運行"); return; } } catch { }//訪問某些進程的MainModule會引發異常,必須波或 } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FmMain()); } } }
