在网上看到一个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.
