我有一个这样的函数,可以通过进程的名称获取进程的id,但它总是在我尝试的每个进程中返回0:
DWORD GetProcessId(std::string ProcessName)
{
HANDLE hsnap;
PROCESSENTRY32 pt;
DWORD PiD;
hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pt.dwSize = sizeof(PROCESSENTRY32);
do {
if (!strcmp(pt.szExeFile, ProcessName.c_str())) {
CloseHandle(hsnap);
PiD = pt.th32ProcessID;
return PiD;
if (PiD != NULL) {
return 0;
}
}
} while (Process32Next(hsnap, &pt));
return 1;
}
主要功能:
int main()
{
DWORD pid = GetProcessId("calc.exe");
std::cout << pid;
if (pid == 0) { printf("error 1"); getchar(); }//error
return 0;
}
这里有几个问题。
首先,GetProcessId
是Windows API函数的名称,它以单个HANDLE
作为参数。HANDLE
通常被定义为void*
,因此这意味着任何指针都将满足函数签名。
您自己的GetProcessId
接受std::string
,但您通过向它传递一个指向字符串常量的指针来调用它。通常情况下,这是可以的,std::string
可以由其构建,但由于GetProcessId
的Windows API版本已经与编译器首选的函数签名匹配。所以基本上你自己的函数从来没有被调用过。
你自己的功能也有几个问题。首先,循环中的第一次迭代是与垃圾内存进行比较——您忘记了调用Process32First
,因此pt
在第一次循环中未初始化。其次,如果找不到进程,则会泄漏hsnap
句柄。
尝试以下操作:
DWORD MyGetProcessId(LPCTSTR ProcessName) // non-conflicting function name
{
PROCESSENTRY32 pt;
HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pt.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hsnap, &pt)) { // must call this first
do {
if (!lstrcmpi(pt.szExeFile, ProcessName)) {
CloseHandle(hsnap);
return pt.th32ProcessID;
}
} while (Process32Next(hsnap, &pt));
}
CloseHandle(hsnap); // close handle on failure
return 0;
}
int main()
{
DWORD pid = MyGetProcessId(TEXT("calc.exe"));
std::cout << pid;
if (pid == 0) { printf("error 1"); getchar(); }//error
return 0;
}
编辑:我已经将函数更改为不再使用std::string
,使用lstrcmpi
意味着它将作为Ansi或Unicode构建工作。正如下面的评论员所建议的那样,现在你真的应该使用Unicode。
这是c代码,在windows上运行良好。用进程名称调用PID_GetProcessId,返回进程名称的进程id
int PID_GetProcessId(char * name, PDWORD pid)
{
DWORD aProcesses[1024], cbNeeded, cProcesses;
UINT32 i;
if (!EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
{
//Error
}
/* Calculate how many process identifiers were returned. */
cProcesses = cbNeeded / sizeof(DWORD);
/* Print the name and process identifier for each process. */
for ( i = 0; i < cProcesses; i++ )
{
if( aProcesses[i] != 0 )
{
if(PID_PrintProcessNameAndID( aProcesses[i], name ) == 1)
{
*pid = aProcesses[i];
break;
}
}
}
return 0;
}
int PID_PrintProcessNameAndID(DWORD processID,char * name)
{
char szProcessName[MAX_PATH];
HANDLE hProcess=NULL;
char buff[200]="";
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,FALSE, processID );
/* Get the process name. */
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
{
GetModuleBaseNameA( hProcess, hMod, (LPSTR)szProcessName, sizeof(szProcessName)/sizeof(TCHAR) );
}
}
if(lstrcmpiA(szProcessName, name) == 0)
{
CloseHandle(hProcess);
return 1;
}
return 0;
CloseHandle( hProcess );
}