日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C/C++:Windows编程—创建进程、终止进程、枚举进程、枚举线程、枚举DLL

發(fā)布時間:2025/3/15 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C/C++:Windows编程—创建进程、终止进程、枚举进程、枚举线程、枚举DLL 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

創(chuàng)建進(jìn)程的2種方式

1. 創(chuàng)建進(jìn)程最簡單的方法

UINT WINAPI WinExec(_In_ LPCSTR lpCmdLine, // 指向可執(zhí)行文件_In_ UINT uCmdShow // 程序運(yùn)行后的窗口狀態(tài) );

2. CreateProcess函數(shù)創(chuàng)建進(jìn)程

通常情況下,創(chuàng)建一個進(jìn)程會選擇CreateProcess函數(shù),該函數(shù)的參數(shù)非常多,功能強(qiáng)大,使用也更為靈活。

https://docs.microsoft.com/zh-cn/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessa

BOOL CreateProcessA(LPCSTR lpApplicationName, // 應(yīng)用程序名LPSTR lpCommandLine, // 命令行參數(shù)LPSECURITY_ATTRIBUTES lpProcessAttributes, // 進(jìn)程安全屬性LPSECURITY_ATTRIBUTES lpThreadAttributes, // 線程安全屬性BOOL bInheritHandles, // 當(dāng)前進(jìn)程中的可繼承句柄是否被新進(jìn)程繼承DWORD dwCreationFlags, // 新進(jìn)程的優(yōu)先級以及其他創(chuàng)建標(biāo)志// DEBUG_PROCESS,DEBUG_ONLY_THIS_PROCESS,CREATE_SUSPENDED ResumeThread() 進(jìn)行恢復(fù)LPVOID lpEnvironment, // 新進(jìn)程的環(huán)境變量 通常這里指定為NULLLPCSTR lpCurrentDirectory, // 指定新進(jìn)程使用的當(dāng)前目錄LPSTARTUPINFOA lpStartupInfo, // 新進(jìn)程的啟動信息,指向STARTUPINFO結(jié)構(gòu)體LPPROCESS_INFORMATION lpProcessInformation //用于返回新進(jìn)程和主線程的相關(guān)信息,指向PROCESS_INFORMATION結(jié)構(gòu)體 );typedef struct _STARTUPINFOA {DWORD cb;LPSTR lpReserved;LPSTR lpDesktop;LPSTR lpTitle;DWORD dwX;DWORD dwY;DWORD dwXSize;DWORD dwYSize;DWORD dwXCountChars;DWORD dwYCountChars;DWORD dwFillAttribute;DWORD dwFlags;WORD wShowWindow;WORD cbReserved2;LPBYTE lpReserved2;HANDLE hStdInput;HANDLE hStdOutput;HANDLE hStdError; } STARTUPINFOA, *LPSTARTUPINFOA; // 該結(jié)構(gòu)體在使用前,需要對cb進(jìn)行賦值,用戶保存結(jié)構(gòu)體的大小 // 如果要對新進(jìn)程的輸入輸出重定向的話,會用到該結(jié)構(gòu)體的更多成員// https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/ns-processthreadsapi-process_information typedef struct _PROCESS_INFORMATION {HANDLE hProcess;HANDLE hThread;DWORD dwProcessId;DWORD dwThreadId; } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; // 該結(jié)構(gòu)體用于返回 新創(chuàng)建進(jìn)程的句柄和進(jìn)程ID,進(jìn)程主線程的句柄和主線程ID,進(jìn)程創(chuàng)建后 這2個句柄需要關(guān)閉

示例代碼

#include <windows.h> #include <stdio.h> #define EXEC_FILE "c:\\windows\\system32\\notepad.exe"int main() {// 必須初始化 STARTUPINFOA sInfo = {0};sInfo.cb = sizeof(sInfo); PROCESS_INFORMATION pInfo = {0};BOOL ret = CreateProcessA(EXEC_FILE,NULL,NULL,NULL,FALSE,NULL,NULL,NULL,&sInfo,&pInfo);if(!ret){printf("創(chuàng)建進(jìn)程失敗");} else{printf("創(chuàng)建進(jìn)程成功");}CloseHandle(pInfo.hProcess);CloseHandle(pInfo.hThread); return 0; }

終止進(jìn)程

進(jìn)程正常退出時,會調(diào)用ExitProcess函數(shù),調(diào)用SendMessage函數(shù)發(fā)送WM_CLOSE消息到目標(biāo)窗口的方法,這種方法通常也會讓程序正常結(jié)束而退出。本節(jié) 介紹 強(qiáng)制結(jié)束指定進(jìn)程。使用OpenProcess獲取進(jìn)程句柄,然后TerminateProcess終止進(jìn)程。

  • 結(jié)束指定進(jìn)程的示例代碼
  • // 強(qiáng)制退出進(jìn)程 int ExitProcess() {HWND hWnd = FindWindow(NULL,"無標(biāo)題 - 記事本");if( hWnd == NULL ){printf("FindWindow 失敗");return -1;} DWORD pid = 0;GetWindowThreadProcessId(hWnd,&pid);if( pid == 0){printf("GetWindowThreadProcessId 失敗");return -1;}HANDLE hNote = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);if( hNote == NULL ){printf("OpenProcess 失敗");return -1;}BOOL ret = TerminateProcess(hNote,-1);if( ret ){printf("成功退出"); }else{printf("TerminateProcess 失敗");return -1; }return 0; }
  • 結(jié)束進(jìn)程所用的API函數(shù)說明
  • FindWindow() // 查找窗口

    // 獲取進(jìn)程ID函數(shù)

    DWORD WINAPI GetWindowThreadProcessId(
    In HWND hWnd, // 窗口句柄
    Out_opt LPDWORD lpdwProcessId // 進(jìn)程ID,傳出參數(shù)
    );

    // 獲取進(jìn)程句柄,error return NULL

    HANDLE WINAPI OpenProcess(
    In DWORD dwDesiredAccess, // 打開進(jìn)程的訪問權(quán)限 PROCESS_ALL_ACCESS
    In BOOL bInheritHandle, // 是否可繼承
    In DWORD dwProcessId // 進(jìn)程ID
    );

    // 結(jié)束進(jìn)程

    BOOL WINAPI TerminateProcess(
    In HANDLE hProcess,
    In UINT uExitCode
    );

    進(jìn)程、線程及DLL枚舉API介紹

    無論是枚舉進(jìn)程還是枚舉進(jìn)程中的DLL文件,方法都是相同的,都是通過創(chuàng)建指定的相關(guān)快照,再通過循環(huán)逐條獲取快照的內(nèi)容。類似的枚舉線程、枚舉堆都是相同的方法,差別只是在創(chuàng)建快照時的參數(shù)不同,逐條獲取快照的內(nèi)容時的API函數(shù)不同而已。

    枚舉進(jìn)程的API函數(shù):CreateToolhelp32Snapshot()、Process32First()、Process32Next()。

    枚舉線程的API函數(shù):CreateToolhelp32Snapshot()、Thread32First()、Thread32Next()。

    枚舉進(jìn)程的DLL文件:CreateToolhelp32Snapshot()、Module32First()、Module32Next()。

    // err,return INVALID_HANDLE_VALUE HANDLE WINAPI CreateToolhelp32Snapshot(// 建立系統(tǒng)快照的類型:TH32CS_SNAPMODULE,TH32CS_SNAPPROCESS,TH32CS_SNAPTHREAD_In_ DWORD dwFlags,// 如果枚舉的是進(jìn)程或者系統(tǒng)中的線程 該參數(shù)為NULL,如果是進(jìn)程的DLL 那么該參數(shù)是進(jìn)程ID_In_ DWORD th32ProcessID );// err,return FALSE BOOL WINAPI Process32First(_In_ HANDLE hSnapshot,_Inout_ LPPROCESSENTRY32 lppe // 輸入輸出 );typedef struct tagPROCESSENTRY32 {DWORD dwSize; // 該成員必須賦值,為結(jié)構(gòu)體的大小DWORD cntUsage;DWORD th32ProcessID; // 進(jìn)程IDULONG_PTR th32DefaultHeapID;DWORD th32ModuleID;DWORD cntThreads;DWORD th32ParentProcessID; // 父進(jìn)程IDLONG pcPriClassBase;DWORD dwFlags;TCHAR szExeFile[MAX_PATH]; // 可執(zhí)行文件的文件名 } PROCESSENTRY32, *PPROCESSENTRY32;BOOL WINAPI Process32Next(_In_ HANDLE hSnapshot,_Out_ LPPROCESSENTRY32 lppe // 傳出參數(shù) );// 枚舉進(jìn)程中加載的DLL 和枚舉系統(tǒng)中的線程都和上2個函數(shù)類似,所不同的是 XXX32First() 和 XXX32Next() 第二個參數(shù)指向的結(jié)構(gòu)體不同 // DLL 指向的結(jié)構(gòu)體 typedef struct tagMODULEENTRY32 {DWORD dwSize;DWORD th32ModuleID;DWORD th32ProcessID;DWORD GlblcntUsage;DWORD ProccntUsage;BYTE *modBaseAddr;DWORD modBaseSize;HMODULE hModule;TCHAR szModule[MAX_MODULE_NAME32 + 1];TCHAR szExePath[MAX_PATH]; } MODULEENTRY32, *PMODULEENTRY32; // 線程 指向的結(jié)構(gòu)體 typedef struct tagTHREADENTRY32 {DWORD dwSize;DWORD cntUsage;DWORD th32ThreadID;DWORD th32OwnerProcessID;LONG tpBasePri;LONG tpDeltaPri;DWORD dwFlags; } THREADENTRY32, *PTHREADENTRY32;

    枚舉進(jìn)程

    HANDLE snapHandele = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);if( INVALID_HANDLE_VALUE == snapHandele){qDebug() << "CreateToolhelp32Snapshot error" ;return;}PROCESSENTRY32 entry = {0};entry.dwSize = sizeof(entry);// 長度必須賦值BOOL ret = Process32First(snapHandele,&entry);int i = 0;while (ret) {QString exeFile = QString::fromWCharArray(entry.szExeFile);ui->processTab->insertRow(i);ui->processTab->setItem(i,0,new QTableWidgetItem(exeFile));ui->processTab->setItem(i,1,new QTableWidgetItem(QString("%1").arg(entry.th32ProcessID)));i++;ret = Process32Next(snapHandele,&entry);}CloseHandle(snapHandele);

    枚舉線程

    下面是停止進(jìn)程,實際上就是停止進(jìn)程的所有線程,就用到了 枚舉線程

    HANDLE snapHandele = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);if( INVALID_HANDLE_VALUE == snapHandele){qDebug() << "CreateToolhelp32Snapshot error" ;return;}THREADENTRY32 entry = {0};entry.dwSize = sizeof(entry);BOOL ret = Thread32First(snapHandele,&entry);while( ret ){if( entry.th32OwnerProcessID == pid){HANDLE tHandle = OpenThread(THREAD_ALL_ACCESS,FALSE,entry.th32ThreadID);if( tHandle == NULL){qDebug() << "OpenThread error,threadId = " << entry.th32ThreadID;}else{DWORD ret = SuspendThread(tHandle);if( ret == -1){qDebug() << "SuspendThread error";}else{qDebug() << "SuspendThread success";}CloseHandle(tHandle);}}ret = Thread32Next(snapHandele,&entry);}CloseHandle(snapHandele);

    枚舉DLL

    HANDLE snapHandele = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE ,pid);if( INVALID_HANDLE_VALUE == snapHandele){qDebug() << "CreateToolhelp32Snapshot error" ;return;}MODULEENTRY32 entry = {0};entry.dwSize = sizeof(entry);// 長度必須賦值BOOL ret = Module32First(snapHandele,&entry);int i = 0;while (ret) {QString dllFile = QString::fromWCharArray(entry.szModule);QString dllPath = QString::fromWCharArray(entry.szExePath);ui->dllTab->insertRow(i);ui->dllTab->setItem(i,0,new QTableWidgetItem(dllFile));ui->dllTab->setItem(i,1,new QTableWidgetItem(QString("%1").arg(dllPath)));i++;ret = Module32Next(snapHandele,&entry);}CloseHandle(snapHandele);

    總結(jié)

    以上是生活随笔為你收集整理的C/C++:Windows编程—创建进程、终止进程、枚举进程、枚举线程、枚举DLL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。