#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <string.h>
#include <psapi.h>
WINAPI int WinMain(HINSTANCE hInstance, HINSTANCE hPreInstacne, LPSTR lpCmdLine, int nCmdShow)
{
HANDLE pHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 process32;
process32.dwSize = sizeof(process32);
BOOL bReturn = Process32First(pHandle,&process32);
wchar_t* dest;
int srcSize = strlen(lpCmdLine);
dest = (wchar_t*)malloc((srcSize+1)*2);
memset(dest,0,(srcSize+1)*2);
mbstowcs(dest,lpCmdLine,srcSize);
*(dest+srcSize) = L'\0'; //dest = L"Twinkstar.exe"
while(bReturn)
{
if(!wcscmp(dest,(wchar_t*)process32.szExeFile))
{
LPSTR path = (LPSTR)malloc(256);
memset(path,0,256);
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS ,FALSE,process32.th32ProcessID);
GetModuleFileNameExA(process,NULL,path,sizeof(path));
printf("%s",path);
free(path);
path = NULL;
break;
}
Process32Next(pHandle,&process32);
}
free(dest);
dest = NULL;
}
需求:编写一个程序,传入进程名字,输出进程所在路径
问题:程序运行后卡死
程序问题比较多,主要是字符串转换错误,字符串比较不一致就会陷入死循环,做了修改,参考一下:
运行参数指定为"winlogon.exe"试一下:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstacne, LPSTR lpCmdLine, int nCmdShow)
{
HANDLE pHandle = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
PROCESSENTRY32 process32;
process32.dwSize = sizeof(process32);
BOOL bReturn = Process32First(pHandle, &process32);
char* dest;
int srcSize = strlen(lpCmdLine);
dest = (char*)malloc(srcSize + 1);
memset(dest, 0, srcSize + 1);
strcpy(dest, lpCmdLine);
*(dest + srcSize) = L'\0'; //dest = L"Twinkstar.exe"
while (bReturn)
{
if (!strcmp(dest, process32.szExeFile))
{
LPSTR path = (LPSTR)malloc(256);
memset(path, 0, 256);
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process32.th32ProcessID);
int nErr = GetLastError();
GetModuleFileNameExA(process, NULL, path, 256);
printf("%s", path);
free(path);
path = NULL;
break;
}
Process32Next(pHandle, &process32);
}
free(dest);
dest = NULL;
}
用管理员权限运行,在循环里输出下每次
process32.szExeFile
看看卡在哪里了
第27行sizeof(path)不对,path不是数组是字符串指针,大小为4,所以你获取的结果只有盘符如c:\加上结尾0刚好4位。
根据您提供的代码,循环似乎是遍历正在运行的进程列表,并尝试匹配目标进程的名称。然后,它打开匹配进程的句柄,并获取其模块文件的路径。
代码中的问题可能导致程序卡死的原因有几个可能性:
如果没有匹配到目标进程,循环将无限执行,因为没有设置终止条件。为了避免这种情况,请添加一个适当的终止条件。
如果找到目标进程并成功获取其模块文件的路径,但在打印路径之前发生了错误,例如调用了无效的句柄或路径字符串,可能会导致程序卡死。请确保在使用路径之前检查返回值和错误条件,以避免潜在的问题。
以下是修复上述问题的修改后的代码:
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <string.h>
#include <psapi.h>
int main()
{
HANDLE pHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 process32;
process32.dwSize = sizeof(process32);
BOOL bReturn = Process32First(pHandle, &process32);
wchar_t* dest;
int srcSize = strlen(lpCmdLine);
dest = (wchar_t*)malloc((srcSize + 1) * 2);
memset(dest, 0, (srcSize + 1) * 2);
mbstowcs(dest, lpCmdLine, srcSize);
*(dest + srcSize) = L'\0'; //dest = L"Twinkstar.exe"
while (bReturn)
{
if (!wcscmp(dest, (wchar_t*)process32.szExeFile))
{
LPSTR path = (LPSTR)malloc(256);
memset(path, 0, 256);
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process32.th32ProcessID);
if (process != NULL)
{
DWORD pathLength = GetModuleFileNameExA(process, NULL, path, 256);
if (pathLength > 0)
{
printf("%s", path);
}
else
{
printf("Failed to get module file name.\n");
}
CloseHandle(process);
}
else
{
printf("Failed to open process.\n");
}
free(path);
path = NULL;
break;
}
bReturn = Process32Next(pHandle, &process32);
}
free(dest);
dest = NULL;
CloseHandle(pHandle);
return 0;
}
请注意,我还添加了对打开句柄和获取模块文件路径的错误检查,并进行了相应的处理。另外,为了使代码在命令行下运行,将WinMain函数更改为main函数。
这些修改应该有助于避免程序卡死,并提供更好的错误处理和调试信息。
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
根据代码和调试信息,循环中的代码看起来没有明显的问题,可能是由于另一个正在运行的进程导致程序卡死。您可以尝试在循环内加入 Sleep()
函数,减少 CPU 的占用,让其他进程有机会运行。
另外,您在使用 GetModuleFileNameExA()
函数时传递的是 sizeof(path)
,这个值是指针变量 path
的大小,而不是指向的缓冲区大小。因此,您需要将第三个参数改为缓冲区的大小,即 256
。
以下是修改后的代码:
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <string.h>
#include <psapi.h>
WINAPI int WinMain(HINSTANCE hInstance, HINSTANCE hPreInstacne, LPSTR lpCmdLine, int nCmdShow)
{
HANDLE pHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 process32;
process32.dwSize = sizeof(process32);
BOOL bReturn = Process32First(pHandle,&process32);
wchar_t* dest;
int srcSize = strlen(lpCmdLine);
dest = (wchar_t*)malloc((srcSize+1)*2);
memset(dest,0,(srcSize+1)*2);
mbstowcs(dest,lpCmdLine,srcSize);
*(dest+srcSize) = L'\0'; //dest = L"Twinkstar.exe"
while(bReturn)
{
if(!wcscmp(dest,(wchar_t*)process32.szExeFile))
{
LPSTR path = (LPSTR)malloc(256);
memset(path,0,256);
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS ,FALSE,process32.th32ProcessID);
GetModuleFileNameExA(process,NULL,path,256); // 将第三个参数改为缓冲区的大小
printf("%s",path);
free(path);
path = NULL;
break;
}
Sleep(10); //加入 Sleep() 函数
bReturn = Process32Next(pHandle,&process32);
}
free(dest);
dest = NULL;
}
希望这可以帮助您解决问题。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
在分析您提供的代码时,我注意到可能会导致程序卡死的一些问题。下面是我找到的问题和建议的更改:
在使用 mbstowcs
函数之前,您使用 strlen
获取了 lpCmdLine
的长度。但是,lpCmdLine
是一个 LPSTR
类型的参数,表示一个指向以 null 结尾的字符串的指针,而不是一个以 null 结尾的字符串本身。因此,您应该使用 strlen(lpCmdLine)
替换为 strlen((const char*)lpCmdLine)
,以将 lpCmdLine
强制转换为 const char*
类型。
在分配内存给 dest
变量之前,您需要确定需要分配的内存大小,而不仅仅是 srcSize
。因为 srcSize
表示源字符串的长度(不包括 null 终止符),而 dest
是一个宽字符字符串。宽字符字符串的长度应该是 srcSize * sizeof(wchar_t)
。因此,您可以将以下行:
dest = (wchar_t*)malloc((srcSize+1)*2);
更改为:
dest = (wchar_t*)malloc((srcSize + 1) * sizeof(wchar_t));
在使用 GetModuleFileNameExA
函数时,您传递了 sizeof(path)
,但是 path
是一个指针,sizeof(path)
将返回指针的大小,而不是指针指向的缓冲区的大小。您可以更改为使用一个固定的缓冲区大小,例如 MAX_PATH
,或者通过 strlen(path) + 1
来获取动态分配缓冲区的大小。
在调用 CreateToolhelp32Snapshot
函数后,您需要检查返回的 pHandle
是否有效,以确保快照成功创建。您可以添加以下代码来检查 pHandle
:
if (pHandle == INVALID_HANDLE_VALUE) {
// 快照创建失败,进行适当的错误处理
return -1;
}
这些是我在代码中注意到的主要问题。请尝试对代码进行相应的更改,看看是否解决了程序卡死的问题。
望采纳。