VC++ 判断进程是否存在的问题
在网上看到一段代码,不懂C++,请问怎么判断存在否,如,qq.exe存在,则弹出个对话框"存在".进程不要区分大小写,请专家明示代码.DWORDGetProcessidF...
在网上看到一段代码,不懂C++,请问怎么判断存在否,如,qq.exe存在,则弹出个对话框"存在". 进程不要区分大小写,请专家明示代码. DWORD GetProcessidFromName(LPCTSTR name)
{
PROCESSENTRY32 pe;
DWORD id=0;
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize=sizeof(PROCESSENTRY32);
if(!Process32First(hSnapshot,&pe))
return 0;
while(1)
{
pe.dwSize=sizeof(PROCESSENTRY32);
if(Process32Next(hSnapshot,&pe)==FALSE)
break;
if(strcmp(pe.szExeFile,name)==0)
{
id=pe.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
return id;
} 展开
{
PROCESSENTRY32 pe;
DWORD id=0;
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize=sizeof(PROCESSENTRY32);
if(!Process32First(hSnapshot,&pe))
return 0;
while(1)
{
pe.dwSize=sizeof(PROCESSENTRY32);
if(Process32Next(hSnapshot,&pe)==FALSE)
break;
if(strcmp(pe.szExeFile,name)==0)
{
id=pe.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
return id;
} 展开
展开全部
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //创建系统进程列表快照,返回一个快照的句柄。不懂快照、句柄是什么意思的话自己百度,简单的理解的话快照类似于数据库中的视图,而句柄就是一个无符号整数,相当于一个ID。
pe.dwSize=sizeof(PROCESSENTRY32); //这一句就是显式地指明PROCESSENTRY32结构体的大小,看似有些多余,但是MSDN上说不能省略,我自己测试的时候省略也会出错。
if(!Process32First(hSnapshot,&pe)) return 0; //这一句调用Process32First开始遍历快照中的进程列表,把进程的信息拷贝到pe这个数据结构中。如果失败返回FALSE,也就不需要执行后续的Process32Next遍历整个列表了。这个函数跟Process32Next配合可以逐个遍历进程列表,Process32Next参数跟Process32First一样,也同样失败返回FALSE,成功就会一个接一个逐个地把进程列表中快照中的进程的信息拷贝到pe这个数据结构中。值得一提的是,正是由于采用的是进程快照的方式获取进程的信息,所以如果在这个过程中某个或某些进程被其他程序关闭或者自己结束,或者进程队列中加入了新的进程,hSnapShot指向的快照中不会反映这个变化。SnapShot就好比给人拍张照,记录的只是一个人瞬间的样貌,但是从哲学上讲事物都是运动的,无法代表这个人的现状,同样这里的进程快照能够反映的也只是创建快照时系统的进程队列中全部进程的状况。使用快照的好处是什么呢?就是不需要在后面的获取进程的信息时每次都重新反复地获取系统中的进程的列表,而是以快照的方式存储起来,所以速度比较快,也利于保护数据。缺点就是没有实时性。但是一般情况下快照就够用了。
if(strcmp(pe.szExeFile,name)==0) //这个很好理解,就是比较pe.szExeFile和name是否一样,具体的比较方法是比较两者的ASCII码的差值,不懂ASCII码和strcmp的话自己百度,不解释。
id=pe.th32ProcessID;
return id;
这两句放在一起看作用就是返回进程的PID,就是CMD TASKLIST中看到的那个PID,是用来唯一标识进程的ID。后续的OpenProcess访问进程的操作需要的就是这个ID。你用OpenProcess可以得到进程的句柄hProcess,然后调用TerminateProcess hProcess,0就能够强制结束一般的进程了。
中间的CloseHandle(hSnapshot); //这一句可以理解为垃圾回收,作用就是释放掉用CreateToolhelp32Snapshot创建的快照句柄标识的内存空间。
另外,楼下那位朋友说的很对,你的代码无法做到不区分大小写的比较进程名称。所以最好自己添加个处理过程统一下大小写。我给个不用CString的实现方法,仅供参考:
其实就是自己先编写个全部转换为大写的函数然后再比较。
//内联函数,用来返回空字符串。
inline char* DefReturn()
{
char *ret = new char[1];
ret[0] = '\0';
return ret;
}
char* UCase(char *chOri)
{
if(chOri == NULL) return DefReturn();
size_t nLen = strlen(chOri);
if(nLen)
{
char *chRet = new char[nLen+1];
for(size_t index = 0; index<nLen; index++)
{
chRet[index] = toupper(chOri[index]);
}
chRet[index] = '\0';
return chRet;
}
else
{
return chOri;
}
}
//全部转化内大写后开始比较
if(strcmp(UCase(pe.szExeFile),UCase(name))==0)
{
id=pe.th32ProcessID;
break;
}
pe.dwSize=sizeof(PROCESSENTRY32); //这一句就是显式地指明PROCESSENTRY32结构体的大小,看似有些多余,但是MSDN上说不能省略,我自己测试的时候省略也会出错。
if(!Process32First(hSnapshot,&pe)) return 0; //这一句调用Process32First开始遍历快照中的进程列表,把进程的信息拷贝到pe这个数据结构中。如果失败返回FALSE,也就不需要执行后续的Process32Next遍历整个列表了。这个函数跟Process32Next配合可以逐个遍历进程列表,Process32Next参数跟Process32First一样,也同样失败返回FALSE,成功就会一个接一个逐个地把进程列表中快照中的进程的信息拷贝到pe这个数据结构中。值得一提的是,正是由于采用的是进程快照的方式获取进程的信息,所以如果在这个过程中某个或某些进程被其他程序关闭或者自己结束,或者进程队列中加入了新的进程,hSnapShot指向的快照中不会反映这个变化。SnapShot就好比给人拍张照,记录的只是一个人瞬间的样貌,但是从哲学上讲事物都是运动的,无法代表这个人的现状,同样这里的进程快照能够反映的也只是创建快照时系统的进程队列中全部进程的状况。使用快照的好处是什么呢?就是不需要在后面的获取进程的信息时每次都重新反复地获取系统中的进程的列表,而是以快照的方式存储起来,所以速度比较快,也利于保护数据。缺点就是没有实时性。但是一般情况下快照就够用了。
if(strcmp(pe.szExeFile,name)==0) //这个很好理解,就是比较pe.szExeFile和name是否一样,具体的比较方法是比较两者的ASCII码的差值,不懂ASCII码和strcmp的话自己百度,不解释。
id=pe.th32ProcessID;
return id;
这两句放在一起看作用就是返回进程的PID,就是CMD TASKLIST中看到的那个PID,是用来唯一标识进程的ID。后续的OpenProcess访问进程的操作需要的就是这个ID。你用OpenProcess可以得到进程的句柄hProcess,然后调用TerminateProcess hProcess,0就能够强制结束一般的进程了。
中间的CloseHandle(hSnapshot); //这一句可以理解为垃圾回收,作用就是释放掉用CreateToolhelp32Snapshot创建的快照句柄标识的内存空间。
另外,楼下那位朋友说的很对,你的代码无法做到不区分大小写的比较进程名称。所以最好自己添加个处理过程统一下大小写。我给个不用CString的实现方法,仅供参考:
其实就是自己先编写个全部转换为大写的函数然后再比较。
//内联函数,用来返回空字符串。
inline char* DefReturn()
{
char *ret = new char[1];
ret[0] = '\0';
return ret;
}
char* UCase(char *chOri)
{
if(chOri == NULL) return DefReturn();
size_t nLen = strlen(chOri);
if(nLen)
{
char *chRet = new char[nLen+1];
for(size_t index = 0; index<nLen; index++)
{
chRet[index] = toupper(chOri[index]);
}
chRet[index] = '\0';
return chRet;
}
else
{
return chOri;
}
}
//全部转化内大写后开始比较
if(strcmp(UCase(pe.szExeFile),UCase(name))==0)
{
id=pe.th32ProcessID;
break;
}
展开全部
Process32Next(hSnapshot,&pe) //Process32Next函数遍历进程的句柄
strcmp(pe.szExeFile,name) //判断进程名字和输入字符串是否匹配
如果有匹配,函数返回id,没有匹配,返回0
需要说明的是,因为使用的是strcmp==0,所以只能完整匹配,也就是说,如果进程名字大小写没法处理,而如果不完全一致,也不能找到。
如果工程环境允许,那么CString处理比较方便,如下:
CString str = pe.szExeFile;
CString strin = name;
str.MakeLower();
strin.MakeLower();
if(str.Find(strin)>=0) //有包含
{
id = ...;
break;
}
strcmp(pe.szExeFile,name) //判断进程名字和输入字符串是否匹配
如果有匹配,函数返回id,没有匹配,返回0
需要说明的是,因为使用的是strcmp==0,所以只能完整匹配,也就是说,如果进程名字大小写没法处理,而如果不完全一致,也不能找到。
如果工程环境允许,那么CString处理比较方便,如下:
CString str = pe.szExeFile;
CString strin = name;
str.MakeLower();
strin.MakeLower();
if(str.Find(strin)>=0) //有包含
{
id = ...;
break;
}
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询