在網上看到一個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.

