Win32编程4-进程读取,创建,销毁

4 篇文章 0 订阅

先放图vkir6J.md.png

首先是读取进程,其中的PROCESSENTRY32是用来存放快照进程信息的一个结构体。(存放进程信息和调用成员输出进程信息)用来Process32First指向第一个进程信息,并将进程信息抽取到PROCESSENTRY32中。用Process32Next指向下一条进程信息。故可以用while循环不停的获取进程id以及进程名并存放到info中,然后跟注册表一样用字符串拼接起来,返回到过程处理函数并显示到编辑框内。

CString ReadProcess()
{
HANDLE handle;
CString res = TEXT("进程ID    进程名\r\n");
//调用CreatToolhelp32Snapshot来获取快照,用THREADENTRY32来获取线程信息等 就会用到'tlHelp32.h'头文件
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
PROCESSENTRY32 *info = new PROCESSENTRY32;
info->dwSize = sizeof(PROCESSENTRY32);
Process32First(handle, info);
while (Process32Next(handle, info) != FALSE)
{
    DWORD PID = info->th32ProcessID;    //获取进程ID  
    wchar_t *ExeName = info->szExeFile;    //获取进程的EXE名(注意不是全路径)
    CString temp;
    temp.Format(TEXT("%d"), PID);
    res += temp;
    res += TEXT("       ");
    res += ExeName;
    res += TEXT("\r\n");
    PROCESSENTRY32 *copyInfo = new PROCESSENTRY32;    //将造成内存泄漏
    copyInfo = info;
    ProResult.push_back(copyInfo);    //进程结构体PROCESSENTRY32存入vector
}
return res;
}

接着是创建进程,其中的STARTUPINFO结构是用于指定新进程的主窗口特性,cb成员是该结构的字节数。

typedef struct _PROCESS_INFORMATION {
 HANDLE hProcess; //存放每个对象的与进程相关的句柄
 HANDLE hThread;         //返回的线程句柄。
 DWORD dwProcessId;     //用来存放进程ID号
 DWORD dwThreadId;       //用来存放线程ID号
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;

PROCESS_INFORMATION结构在调用Createprocess函数后,系统会自动地对该结构进行填充。内部如上所示。一目了然,由于是系统自动填充,所以我们可以不用深究,如果感兴趣可以自己百度了解一下。

pszFilePath是全局函数,与读取文件时调用的是同一个函数OpenDlg,该函数通过打开一个对话框选择exe文件来获取文件路径并赋值给pszFilePath,以此来创建进程,CreateProcess函数的第二个参数是一个命令参数(大概这个意思),比如打开浏览器进程,第二个参数传入一个包含网址的字符串,可以在打开浏览器的时候自动打开该网站,具体可以自己了解一下。

void CreatePro()
{
STARTUPINFO stStartUpInfo;
memset(&stStartUpInfo, 0, sizeof(stStartUpInfo));
stStartUpInfo.cb = sizeof(stStartUpInfo);
PROCESS_INFORMATION stProcessInfo;
memset(&stProcessInfo, 0, sizeof(stProcessInfo));
bool bRet = CreateProcess(
    pszFilePath,
    NULL,
    NULL,
    NULL,
    false,
    CREATE_NEW_CONSOLE,
    NULL,
    NULL,
    &stStartUpInfo,
    &stProcessInfo);
if (bRet)
{
    //等待3s后关闭进程
    WaitForSingleObject(stProcessInfo.hProcess, 3000L);
    CloseHandle(stProcessInfo.hProcess);
    CloseHandle(stProcessInfo.hThread);
    stProcessInfo.hProcess = NULL;
    stProcessInfo.hThread = NULL;
    stProcessInfo.dwProcessId = 0;
    stProcessInfo.dwThreadId = 0;
}
else
{
    //如果创建进程失败,查看错误码
    DWORD dwErrCode = GetLastError();
    printf_s("ErrCode : %d\n", dwErrCode);
}

}

最后是结束进程,通过输入读取进程时获取的pid来结束进程,但是用TerminateProcess结束进程好像不是很安全,会导致资源没有正确释放,但这里不多探索,毕竟只是练手,点到为止。

函数过程也比较好理解,先获取用户输入的数字并判空,然后用wchar_t字符串接收,接着转换为DWORD类型,通过PID获取进程句柄,然后通过句柄来销毁进程,相当简单,这里不过多赘述。

void EndPro(HWND hwnd, HWND h)
{
DWORD nID;
HANDLE hPro;
DWORD n = GetWindowTextLength(hwnd);
if (n == 0)
{
    MessageBox(h, TEXT("请输入一个数字"), TEXT("提示"), MB_OK);
    return;
}
wchar_t* temp = new wchar_t[n + 1];
GetWindowText(hwnd, temp, n + 1);
CString t = temp;
nID = _tcstoul(t, NULL, 10);
//获得进程 ID,后通过进程 ID 获得进程句柄
hPro = OpenProcess(PROCESS_ALL_ACCESS,FALSE,nID);
if (TerminateProcess(hPro, 0) != 0)
{
    MessageBox(h, TEXT("销毁成功"), TEXT("提示"), MB_OK);
    return;
}
else
{
    MessageBox(h, TEXT("销毁失败"), TEXT("提示"), MB_OK);
    return;
}
}

到这里win32编程的练手项目就结束了,总而言之不算难,基本就是调用api进行处理,难得主要是要用正确的类型和大小来接收结果,特别是诸如LPSTR,LPSCSTR,LPCSWSTR,LPWSTR,长得挺像,但含义却不一样,一开始接触有点头大,毕竟只看了一点入门视频(小甲鱼)的就开始写demo,许多类型都是第一次见,断断续续摸了两个多星期才完结,实际上每天用来写的时间也就两三个小时,出个bug就要改好久,在家效率果然低,但也算是有收获,起码知道了一些关于注册表以及进程的知识,也不是很多,肯定还要继续深入的了解。

第一次写博客有点生疏,感觉不够细节,主要还是自己太懒,以后会更加注重这方面,博客也会持续更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值