using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace SiaSun.LMS.Common
{
    /// <summary>
    /// 应用程序唯一运行实例实现
    /// 即当前系统只能打开一个SiasunLMS程序实例
    /// </summary>
    public static class SingleInstance
    {
        /// <summary>
        /// 获得正在运行的程序实例线程
        /// </summary>
        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;

        /// <summary>
        /// 对其进一步包装,HandleRunningInstance静态方法为获取应用程序句柄,设置应用程序为前台运行,并返回bool值。 
        /// </summary>
        /// <param name="instance">进程实例</param>
        public static bool HandleRunningInstance(Process instance)
        {
            //确保窗口没有被最小化或最大化 
            ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
            //设置为foreground window 
            return SetForegroundWindow(instance.MainWindowHandle);
        }

        /// <summary>
        /// 判断是否实例是否存在
        /// </summary>
        public static bool HandleRunningInstance()
        {
            Process p = GetRunningInstance();
            if (p != null)
            {
                HandleRunningInstance(p);
                return true;
            }
            return false;
        }
    }
}