当前位置: 代码迷 >> WinCE >> WINCE程序只运行一个,防止多重运作
  详细解决方案

WINCE程序只运行一个,防止多重运作

热度:247   发布时间:2016-04-28 11:51:13.0
WINCE程序只运行一个,防止多重运行。

在 winform中,程序只运行一个,防止多重运行,很容易。如用FindWindow、Mutex和C#直接Process遍历,都可以实现。

但是,到了WINCE 系统中,要么方法不存在,即使引入CreateMutex,也是白搭。根本无效。

从网上找到一篇通过系统快照方式的方案。不过,大侠们写的都不完整,我特地贡献一个可以直接使用的类:

using System.IO;
using System.Runtime.InteropServices;

//可能还缺其他using,,,,没仔细看。

    public class MyProcess
    {
        #region //导入dll中函数
        [DllImport("Toolhelp.dll")]
        private static extern IntPtr CreateToolhelp32Snapshot(uint flags, uint processid);
        [DllImport("Toolhelp.dll")]
        private static extern int CloseToolhelp32Snapshot(IntPtr handle);
        [DllImport("Toolhelp.dll")]
        private static extern int Process32First(IntPtr handle, ref PROCESSENTRY32 pe);
        [DllImport("Toolhelp.dll")]
        private static extern int Process32Next(IntPtr handle, ref PROCESSENTRY32 pe);
        #endregion
        #region //定义信息结构体
        [StructLayout(LayoutKind.Sequential)]
        private struct PROCESSENTRY32
        {
            public uint dwSize;
            public uint cntUsage;
            public uint th32ProcessID;
            public IntPtr th32DefaultHeapID;
            public uint th32ModuleID;
            public uint cntThreads;
            public uint th32ParentProcessID;
            public int pcPriClassBase;
            public uint dwFlags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]//注意,此处为宽字符
            public string szExeFile;
            public uint th32MemoryBase;
            public uint th32AccessKey;
        }

        private enum SnapShotFlags : uint
        {
            TH32CS_SNAPHEAPLIST = 0x00000001,
            TH32CS_SNAPPROCESS = 0x00000002,
            TH32CS_SNAPTHREAD = 0x00000004,
            TH32CS_SNAPMODULE = 0x00000008,
            TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE),
            TH32CS_GETALLMODS = 0x80000000
        }
        #endregion

        public static bool CheckIsRunning()
        {
            bool IsRunning = false;
            int nCount=0;

            string AppName = System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).ToLower();
            //获取当前程序名称,有个缺陷,运行一次后,修改程序名称,可以再次运行,函数却检测不到。哪位大小有更好的检测项目??

            IntPtr handle = CreateToolhelp32Snapshot((uint)SnapShotFlags.TH32CS_SNAPPROCESS, 0);//获取所有进程快照,包括自己。
            if ((int)handle != -1)
            {
                PROCESSENTRY32 pe32 = new PROCESSENTRY32();
                pe32.dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32));
                int bMore = Process32First(handle, ref pe32);//遍历进程快照,获取每个进程的信息
                //PROCESSENTRY32 pe;
                while (bMore == 1)
                {
                    //IntPtr temp = Marshal.AllocHGlobal((int)pe32.dwSize);//非托管,分配内存
                    //Marshal.StructureToPtr(pe32, temp, true);//将进程结构信息,传送到非托管内存块temp。
                    //pe = (PROCESSENTRY32)Marshal.PtrToStructure(temp, typeof(PROCESSENTRY32));
                    //Marshal.FreeHGlobal(temp);/////////////////////////////将分配的内存释放
                    //MessageBox.Show(pe32.szExeFile); //以上语句怎么都没想明白到底用来干啥????有啥用?那位大侠解释一下!
                    if (pe32.szExeFile.ToString().ToLower() == AppName)
                    {
                        nCount++;//因为包括自己,所以必须设计计数器。
                        if (nCount > 1)
                        {
                            IsRunning = true;
                            break;
                        }
                    }
                    bMore = Process32Next(handle, ref pe32);//遍历进程快照,获取下一个进程的信息
                }
            }
            //CloseHandle(handle);//winCE 中,这个函数关闭快照无效,
            CloseToolhelp32Snapshot(handle);//wince 中,必须用这个函数才能关闭快照。

            return IsRunning;
        }
    }

版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案