C#程序防多開又一法


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM