在網上看到一個C++代碼示例:
原文地址:http://bbs.pediy.com/thread-217610.htm
覺得這是一個很好的調用 windows api 的示例,故將其轉換成了 delphi xe8
源碼下載:OpenNewWechat
下面給出所用到的windows api 定義
unit uWinApi; // http://bbs.pediy.com/thread-217610.htm // 微信(WeChat)電腦端多開分析+源碼 { 感謝原文提供的代碼和 exe 曉不得2013 qq 26562729 2017-07-04 // 本代碼是學習 win api 的一個經典示例 // 希望您會有所收獲 } interface uses windows, TLHelp32, Generics.collections; type PSystemHandle = ^TSystemHandle; // 此結構體未公開,找了很久才弄正確。 TSystemHandle = packed record // 共16字節. 長度一定要准確。否則,后面沒法玩。 dwProcessID: THandle; bObjectType: Byte; bflags: Byte; wValue: Word; GrantedAcess: Int64; end; PSystemHandleList = ^TSystemHandleList; TSystemHandleList = record dwHandleCount: Cardinal; // 獲取到的結果前4個字節,表示數量 // 后面的就每 16 個字節一組,表示一個 TSystemHandle Handles: array of TSystemHandle; // 定義成下面這樣,亦可行。 // Handles:TSystemHandle; 只是不便於理解 end; PProcessRec = ^TProcessRec; TProcessRec = record ProcessName: string; ProcessID: THandle; end; TProcessRecList = class(TList<PProcessRec>) public procedure FreeAllItem; end; // win 規則下,都是讓調用者傳入 buff 長度,然后檢查這個長度是否合適 // 如果不夠,就返回一個錯誤,並且在 ASize 中指明需要的長度 // 以便調用者重新分配 buff 再次調用 // ASysInfoCls 是查詢什么類別。 MS 沒有全部公開. $10 為 SystemHanle. // ASysInfo 理解為 Buff 就行了。 function ZwQuerySystemInformation(ASysInfoCls: Integer; ASysInfo: Pointer; ABufLen: Cardinal; var ASize: Cardinal): Cardinal; stdcall; external 'ntdll.dll'; function NtQueryObject(Ahandle: THandle; AQuertyIndex: Integer; ABuff: Pointer; ABuffSize: Cardinal; var ASize: Cardinal): Cardinal; stdcall; external 'ntdll.dll'; // 獲取當前的進程 function GetAllProcess: TProcessRecList; implementation { TProcessRecList } procedure TProcessRecList.FreeAllItem; var p: PProcessRec; begin for p in self do Dispose(p); end; function GetAllProcess: TProcessRecList; var Entry32: TProcessEntry32W; SnapshotHandle: THandle; Found: boolean; sExeFileName: string; p: PProcessRec; begin Result := TProcessRecList.Create; SnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); Entry32.dwSize := sizeof(Entry32); Found := Process32First(SnapshotHandle, Entry32); while Found do begin new(p); Result.Add(p); sExeFileName := Entry32.szExeFile; p.ProcessName := sExeFileName; p.ProcessID := Entry32.th32ProcessID; Found := Process32Next(SnapshotHandle, Entry32); end; CloseHandle(SnapshotHandle); end; end.