在 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;
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。