• 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;
    }

    其他相关代码
    其他相关代码
  • 相关阅读:
    ThinkPHP框架知识(比较全的知识)
    利用smarty模板(登录、有关信息操作等功能)
    从零开始学习Node.js例子七 发送HTTP客户端请求并显示响应结果
    从零开始学习Node.js例子六 EventEmitter发送和接收事件
    从零开始学习Node.js例子五 服务器监听
    从零开始学习Node.js例子四 多页面实现数学运算 续二(client端和server端)
    从零开始学习Node.js例子四 多页面实现数学运算 续一(使用connect和express框架)
    从零开始学习Node.js例子四 多页面实现数学运算
    从零开始学习Node.js例子三 图片上传和显示
    从零开始学习Node.js例子二 文本提交与显示
  • 原文地址:https://www.cnblogs.com/anjou/p/1232625.html
Copyright © 2020-2023  润新知