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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

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

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

創建進程的2種方式

1. 創建進程最簡單的方法

UINT WINAPI WinExec(_In_ LPCSTR lpCmdLine, // 指向可執行文件_In_ UINT uCmdShow // 程序運行后的窗口狀態 );

2. CreateProcess函數創建進程

通常情況下,創建一個進程會選擇CreateProcess函數,該函數的參數非常多,功能強大,使用也更為靈活。

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

BOOL CreateProcessA(LPCSTR lpApplicationName, // 應用程序名LPSTR lpCommandLine, // 命令行參數LPSECURITY_ATTRIBUTES lpProcessAttributes, // 進程安全屬性LPSECURITY_ATTRIBUTES lpThreadAttributes, // 線程安全屬性BOOL bInheritHandles, // 當前進程中的可繼承句柄是否被新進程繼承DWORD dwCreationFlags, // 新進程的優先級以及其他創建標志// DEBUG_PROCESS,DEBUG_ONLY_THIS_PROCESS,CREATE_SUSPENDED ResumeThread() 進行恢復LPVOID lpEnvironment, // 新進程的環境變量 通常這里指定為NULLLPCSTR lpCurrentDirectory, // 指定新進程使用的當前目錄LPSTARTUPINFOA lpStartupInfo, // 新進程的啟動信息,指向STARTUPINFO結構體LPPROCESS_INFORMATION lpProcessInformation //用于返回新進程和主線程的相關信息,指向PROCESS_INFORMATION結構體 );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; // 該結構體在使用前,需要對cb進行賦值,用戶保存結構體的大小 // 如果要對新進程的輸入輸出重定向的話,會用到該結構體的更多成員// 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; // 該結構體用于返回 新創建進程的句柄和進程ID,進程主線程的句柄和主線程ID,進程創建后 這2個句柄需要關閉

示例代碼

#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("創建進程失敗");} else{printf("創建進程成功");}CloseHandle(pInfo.hProcess);CloseHandle(pInfo.hThread); return 0; }

終止進程

進程正常退出時,會調用ExitProcess函數,調用SendMessage函數發送WM_CLOSE消息到目標窗口的方法,這種方法通常也會讓程序正常結束而退出。本節 介紹 強制結束指定進程。使用OpenProcess獲取進程句柄,然后TerminateProcess終止進程。

  • 結束指定進程的示例代碼
  • // 強制退出進程 int ExitProcess() {HWND hWnd = FindWindow(NULL,"無標題 - 記事本");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; }
  • 結束進程所用的API函數說明
  • FindWindow() // 查找窗口

    // 獲取進程ID函數

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

    // 獲取進程句柄,error return NULL

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

    // 結束進程

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

    進程、線程及DLL枚舉API介紹

    無論是枚舉進程還是枚舉進程中的DLL文件,方法都是相同的,都是通過創建指定的相關快照,再通過循環逐條獲取快照的內容。類似的枚舉線程、枚舉堆都是相同的方法,差別只是在創建快照時的參數不同,逐條獲取快照的內容時的API函數不同而已。

    枚舉進程的API函數:CreateToolhelp32Snapshot()、Process32First()、Process32Next()。

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

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

    // err,return INVALID_HANDLE_VALUE HANDLE WINAPI CreateToolhelp32Snapshot(// 建立系統快照的類型:TH32CS_SNAPMODULE,TH32CS_SNAPPROCESS,TH32CS_SNAPTHREAD_In_ DWORD dwFlags,// 如果枚舉的是進程或者系統中的線程 該參數為NULL,如果是進程的DLL 那么該參數是進程ID_In_ DWORD th32ProcessID );// err,return FALSE BOOL WINAPI Process32First(_In_ HANDLE hSnapshot,_Inout_ LPPROCESSENTRY32 lppe // 輸入輸出 );typedef struct tagPROCESSENTRY32 {DWORD dwSize; // 該成員必須賦值,為結構體的大小DWORD cntUsage;DWORD th32ProcessID; // 進程IDULONG_PTR th32DefaultHeapID;DWORD th32ModuleID;DWORD cntThreads;DWORD th32ParentProcessID; // 父進程IDLONG pcPriClassBase;DWORD dwFlags;TCHAR szExeFile[MAX_PATH]; // 可執行文件的文件名 } PROCESSENTRY32, *PPROCESSENTRY32;BOOL WINAPI Process32Next(_In_ HANDLE hSnapshot,_Out_ LPPROCESSENTRY32 lppe // 傳出參數 );// 枚舉進程中加載的DLL 和枚舉系統中的線程都和上2個函數類似,所不同的是 XXX32First() 和 XXX32Next() 第二個參數指向的結構體不同 // DLL 指向的結構體 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; // 線程 指向的結構體 typedef struct tagTHREADENTRY32 {DWORD dwSize;DWORD cntUsage;DWORD th32ThreadID;DWORD th32OwnerProcessID;LONG tpBasePri;LONG tpDeltaPri;DWORD dwFlags; } THREADENTRY32, *PTHREADENTRY32;

    枚舉進程

    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);

    枚舉線程

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

    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);

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。