功能:可防止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()); } } }