C# Windows 桌面应用只运行一个实例(总结)

1) 根据“程序集的签名”获取已运行的实例
/// <summary>
/// 根据“程序集的签名”获取已运行的实例
///    .EXE 文件改名或路径改变,此方法可正常工作
/// </summary>
/// <param name="runningProcess">前一个实例的 Process</param>
/// <returns>是否有相同的实例在运行 ture/false</returns>
/// <remarks>需要对程序集进行签名。存在问题:速度稍慢。</remarks>
private static bool GetRunningProcessByAssemblyName(out Process runningProcess)
{
    
bool returnValue = false;
    runningProcess 
= null;

    AssemblyName currentAssemblyName 
= 
             AssemblyName.GetAssemblyName(Assembly.GetExecutingAssembly().Location);
    AssemblyName processAssemblyName 
= new AssemblyName();

    Process current 
= Process.GetCurrentProcess();
    Process[] processes 
= Process.GetProcesses();
    
foreach (Process process in processes)
    {
        
// 排除一些其他进程,可以加快点速度。
        if (process.Id != current.Id && 
            process.ProcessName 
!= "System" &&
            process.ProcessName 
!= "csrss" &&
            process.ProcessName 
!= "svchost" && 
            process.ProcessName 
!= "services" &&
            process.ProcessName 
!= "smss" &&
            process.ProcessName 
!= "winlogon" &&
            process.ProcessName 
!= "explorer" &&
            process.ProcessName 
!= "pds" &&
            process.ProcessName 
!= "alg" &&
            process.ProcessName 
!= "msdtc" &&
            process.ProcessName 
!= "spoolsv" &&
            process.ProcessName 
!= "lsass" &&
            process.ProcessName 
!= "Idle" &&
            process.ProcessName 
!= "iexplore" &&
            process.ProcessName 
!= "sqlserver" &&
            process.ProcessName 
!= "notepad" &&
            process.ProcessName 
!= "360tray" &&
            process.ProcessName 
!= "XDict"
            )
        {
            
try
            {
                
// 获取文件的程序集
                processAssemblyName = AssemblyName.GetAssemblyName(process.MainModule.FileName);
            }
            
catch (Exception)
            {
                processAssemblyName 
= null;
            }

            
// 通过 GetPublicKey() 来获取程序集的公钥;需要对程序集签名,否则 GetPublicKey() 返回的是 Null。
            if (processAssemblyName != null &&
                CompareBytes(currentAssemblyName.GetPublicKey(), 
                                     processAssemblyName.GetPublicKey()))
            {
                runningProcess 
= process;
                returnValue 
= true;
                
break;
            }
        }
    }
    
return returnValue;
}

2) 根据“进程名称”获取已运行的实例
/// <summary>
/// 根据“进程名称”获取已运行的实例
/// </summary>
/// <param name="runningProcess">前一个实例的 Process</param>
/// <returns>是否有相同的实例在运行 ture/false</returns>
/// <remarks>存在问题:1)有可能有相同的进程名; 2)修改了文件名,此方法失效。</remarks>
private static bool GetRunningProcessByProcessName(out Process runningProcess)
{
    
bool returnValue = false;
    runningProcess 
= null;

    Process current 
= Process.GetCurrentProcess();
    Process[] processes 
= Process.GetProcessesByName(current.ProcessName);
    
foreach (Process process in processes)
    {
        
if (process.Id != current.Id)
        {
            
if (process.ProcessName == current.ProcessName)
            {
                runningProcess 
= process;
                returnValue 
= true;
                
break;
            }
        }
    }
    
return returnValue;
}

3) 根据“进程名称和路径”获取已运行的实例
/// <summary>
/// 根据“进程名称和路径”获取已运行的实例
/// </summary>
/// <param name="runningProcess">前一个实例的 Process</param>
/// <returns>是否有相同的实例在运行 ture/false</returns>
/// <remarks>存在问题:修改了文件名或改变了文件路径,此方法失效。</remarks>
private static bool GetRunningProcessByProcessFullName(out Process runningProcess)
{
    
bool returnValue = false;
    runningProcess 
= null;

    Process current 
= Process.GetCurrentProcess();
    Process[] processes 
= Process.GetProcessesByName(current.ProcessName);
    
foreach (Process process in processes)
    {
        
if (process.Id != current.Id)
        {
            
if (process.MainModule.FileName ==
               Assembly.GetExecutingAssembly().Location)
            {
                runningProcess 
= process;
                returnValue 
= true;
                
break;
            }
        }
    }
    
return returnValue;
}

4) 根据“Mutex”判断是否有相同的实例在运行
/// <summary>
/// 根据“Mutex”判断是否有相同的实例在运行
/// </summary>
/// <param name="runningProcess">总是 null</param>
/// <returns>是否有相同的实例在运行 ture/false</returns>
/// <remarks>存在问题:不能返回前一个实例的 Process</remarks>
private static bool GetRunningProcessByMutex(out Process runningProcess)
{
    
bool returnValue = false;
    runningProcess 
= null;

    
bool isCreated;
    Mutex m 
= new Mutex(false"OneInstance"out isCreated);
    
if (!(isCreated))
    {
        MessageBox.Show(
"已经有相同的实例在运行。""提示"
             MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    returnValue 
= !isCreated;
    
return returnValue;
}

其他相关代码
其他相关代码
原文地址:https://www.cnblogs.com/anjou/p/1232625.html