• .Net应用程序唯一运行实例


    逻辑处理步骤如下, 
    1.初始化应用程序,启动程序初始化进程; 
    2.访问系统进程列表,根据初始化进程关键信息进行匹配查找; 
    3.没有找到匹配进程(这一步是不会发生的,因为当前初始化进程也在列表中,不过还要看获取进程列表的实现代码怎么写),继续初始化进程,程序初始化完成运行。 
    4.找到第一个匹配进程,判断找到的进程ID是否同初始化进程ID相同; 
    5.如果第一个匹配进程ID同初始化进程ID相同,则为当前初始化进程,继续查找; 
    6.没有找到第二个匹配进程,表明当前运行的是首个实例,继续初始化进程,程序初始化完成运行。 
    7.找到第二个,表明已有一个实例在运行,停止当前程序初始化,提示已有应用程序运行。 
    8.如果找到第一个匹配进程ID不同,表明已有一个实例在运行,停止当前程序初始化,提示已有应用程序运行。 

    可见上面的逻辑实现中用于进程匹配的信息是关键,选择不当功能就无法实现。在这个实例中笔者使用了应用程序完全文件名称作为关键信息。
    在代码中首先需要引用下面命名空间,以调用WinAPI函数。 
    using System.Runtime.InteropServices; 
    把实现唯一运行实例功能的类名取为SingleInstance,在类前面加static关键字为C# 2.0新增的语言特征。 
    public static class SingleInstance {} 
    使用GetRunningInstance静态方法获取应用程序进程实例,如果没有匹配进程,返回Null值, 
    public static Process GetRunningInstance() 

            Process currentProcess = Process.GetCurrentProcess(); //获取当前进程 
            //获取当前运行程序完全限定名 
            string currentFileName = currentProcess.MainModule.FileName; 
            //获取进程名为ProcessName的Process数组。 
            Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName); 
            //遍历有相同进程名称正在运行的进程 
            foreach (Process process in processes) 
            
                    if (process.MainModule.FileName == currentFileName) 
                    
                            if (process.Id != currentProcess.Id) //根据进程ID排除当前进程 
                                    return process;//返回已运行的进程实例 
                    
            
            return null


    接下来调用两个WinAPI,其功能将在包装方法中描述, 
    [DllImport("User32.dll")] 
    private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow); 
    [DllImport("User32.dll")] 
    private static extern bool SetForegroundWindow(IntPtr hWnd); 

    定义类成员辅助变量, 
    private const int WS_SHOWNORMAL = 1; 

    以上的方法声明为私有,对其进一步包装,HandleRunningInstance静态方法为获取应用程序句柄,设置应用程序为前台运行,并返回bool值。 
    public static bool HandleRunningInstance(Process instance) 

            //确保窗口没有被最小化或最大化 
            ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); 
            //设置为foreground window 
            return SetForegroundWindow(instance.MainWindowHandle); 

  • 相关阅读:
    利用string 字符串拷贝
    新手学vim配置
    进程描述符task_struct
    并查集
    堆Heap
    Bitset位图
    排序
    sql时间查询
    javascript 中的 call
    css 笔记——设置禁用中文输入法
  • 原文地址:https://www.cnblogs.com/wangfei1511/p/3638697.html
Copyright © 2020-2023  润新知