API 进程与线程函数

11 篇文章 1 订阅
遍历进程并获取进程路径

代码文件:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses PsAPI;

procedure TForm1.Button1Click(Sender: TObject);
const
  n = 512;
var
  IDArr: array[0..n-1] of DWORD;
  size,i: DWORD;
  buf: array[0..MAX_PATH] of Char;
  pHandle: THandle;
begin
//  FillChar(buf, n, #0); {这样可避免乱码}
  EnumProcesses(@IDArr, n, size);
  for i := 0 to size div SizeOf(DWORD) - 1 do
  begin
    pHandle := OpenProcess(PROCESS_ALL_ACCESS, False, IDArr[i]);
    GetModuleFileNameEx(pHandle, 0, buf, Length(buf)*SizeOf(buf[0]));
    CloseHandle(pHandle);
    Memo1.Lines.Add(buf);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Clear;
  Memo1.Align := alTop;
  Memo1.ScrollBars := ssBoth;
end;

end.

窗体文件:
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 206
  ClientWidth = 447
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 342
    Top = 173
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Memo1: TMemo
    Left = 24
    Top = 8
    Width = 185
    Height = 161
    Lines.Strings = (
      'Memo1')
    TabOrder = 1
  end
end

本例效果图:

代码文件:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses PsAPI; {GetModuleFileNameEx 函数需要它}

{根据窗口句柄获取所在程序路径的函数}
function GetProcessExePath(h: HWND): string;
var
  pid: Cardinal;
  pHandle: THandle;
  buf: array[0..MAX_PATH] of Char;
begin
  {先获取进程 ID}
  GetWindowThreadProcessId(h, @pid);
  {再获取进程句柄}
  pHandle := OpenProcess(PROCESS_ALL_ACCESS, False, pid);
  {获取进程路径}
  GetModuleFileNameEx(pHandle, 0, buf, Length(buf));
  CloseHandle(pHandle);
  Result := buf;
end;

{测试当前程序}
procedure TForm1.Button1Click(Sender: TObject);
var
  path: string;
begin
  path := GetProcessExePath(Handle);
  ShowMessage(path);
end;

{测试记事本 - 需要随便打开一个记事本}
procedure TForm1.Button2Click(Sender: TObject);
var
  wh: HWND;
  path: string;
begin
  wh := FindWindow('Notepad', nil);
  path := GetProcessExePath(wh);
  ShowMessage(path);
end;

end.

窗体文件:
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 116
  ClientWidth = 471
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poDesktopCenter
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 112
    Top = 33
    Width = 233
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 112
    Top = 64
    Width = 233
    Height = 25
    Caption = 'Button2'
    TabOrder = 1
    OnClick = Button2Click
  end
end

GetModuleFileName、GetModuleHandle

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  buf: array[0..MAX_PATH] of Char;
  hinst: HMODULE;
begin
  {获取指定模块的句柄}
  hinst := GetModuleHandle('gdi32.dll');

  {获取模块的路径}
  GetModuleFileName(hinst, buf, Length(buf));
  ShowMessage(buf); {C:\WINDOWS\system32\GDI32.dll}
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  buf: array[0..MAX_PATH] of Char;
begin
  {当 GetModuleFileName 的第一个参数为 0 或 HInstance 时, 会获取当前模块路径}
  GetModuleFileName(0, buf, Length(buf));
  ShowMessage(buf);

  GetModuleFileName(HInstance, buf, Length(buf));
  ShowMessage(buf);

  {获取当前程序路径的常用方法}
  ShowMessage(Application.ExeName);
  ShowMessage(ParamStr(0));
end;

end.

 GetModuleHandle - 获取一个模块(exe 或 dll)的句柄

定义:
GetModuleHandle(
  lpModuleName: PChar {模块名; 只能是映射到当前进程的模块}
): HMODULE;           {返回模块句柄; 0 表示失败}

举例:
//获取当前模块的句柄
var
  s: string;
  h: Cardinal;
begin
  {先取得模块名}
  s := Application.ExeName;
  s := ExtractFileName(s);

  {获取参数只要模块名就够了; 不需要路径(测试中有路径也可以)}
  h := GetModuleHandle(PChar(s));
  ShowMessage(IntToStr(h));       {4194304}
end;


//用 nil 做参数即可获取当前模块的句柄
var
  h: Cardinal;
begin
  h := GetModuleHandle(nil);
  ShowMessage(IntToStr(h));  {4194304}
end;


//获取系统骨干模块 Gdi32.dll 的句柄
var
  h: Cardinal;
begin
  h := GetModuleHandle('Gdi32.dll');
  ShowMessage(IntToStr(h));  {2012151808}
end;


//能不能获取记事本的句柄?
var
  h: Cardinal;
begin
  h := GetModuleHandle('notepad.exe');
  ShowMessage(IntToStr(h));  {0; 失败}

{因为当前进程和记事本的进程是相互独立的;     }
{如果用能够冲破进程、面向全局的 dll 应该可以.}
end;

OpenProcess、GetExitCodeProcess、TerminateProcess (测试强制关闭 OICQ)

/声明:

{返回进程的句柄}
OpenProcess(
  dwDesiredAccess: DWORD;  {访问选项}
  bInheritHandle: BOOL;    {能否继承; True 表示能用 CreateProcess 继承句柄创建新进程}
  dwProcessId: DWORD       {指定进程 ID}
): THandle;                {成功会返回进程句柄; 失败返回 0}

//dwDesiredAccess 可选值:
PROCESS_TERMINATE         = $0001; {允许 TerminateProcess 使用进程句柄来关闭进程}
PROCESS_CREATE_THREAD     = $0002; {允许 CreateRemoteThread 使用进程句柄来创建线程}
PROCESS_VM_OPERATION      = $0008; {允许 VirtualProtectEx 使用进程句柄来改变进程的虚拟内存}
PROCESS_VM_READ           = $0010; {允许 ReadProcessMemory 使用进程句柄从进程的虚拟内存中读取数据}
PROCESS_VM_WRITE          = $0020; {允许 WriteProcessMemory 使用进程句柄向进程的虚拟内存中写入数据}
PROCESS_DUP_HANDLE        = $0040; {允许 DuplicateHandle 把进程句柄当作源句柄或目标句柄进行复制}
PROCESS_CREATE_PROCESS    = $0080; {默认值}
PROCESS_SET_QUOTA         = $0100; {允许 SetProcessWorkingSetSize 使用进程句柄来来设置虚拟内存的上限值}
PROCESS_SET_INFORMATION   = $0200; {允许 SetPriorityClass 使用进程句柄来设置进程优先级}
PROCESS_QUERY_INFORMATION = $0400; {允许 GetExitCodeProcess 或 GetPriorityClass 通过进程句柄读取进程信息}
SYNCHRONIZE               = $00100000; {允许任何等待的函数使用进程句柄}
PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $FFF);  {允许所有权限}


{获取指定进程的退出码}
GetExitCodeProcess(
  hProcess: THandle;    {进程句柄}
  var lpExitCode: DWORD {接收退出码}
): BOOL;                {}


{强制结束(其他)进程}
TerminateProcess(
  hProcess: THandle; {进程句柄}
  uExitCode: UINT    {退出码}
): BOOL;             {}

//提示: 关闭其他程序一般应该是向其主窗口发送 WM_CLOSE 消息, 不行再用这个, 因为它不能关闭其关联的 DLL.


//举例(强行关闭 OICQ 的办法):
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  id: Cardinal;
  wh: HWND;
  ph: THandle;
  ExitCode: DWORD;
begin
  wh := FindWindow('#32770', nil);
  GetWindowThreadProcessId(wh, id);
  ph := OpenProcess(PROCESS_TERMINATE, False, id);
  GetExitCodeProcess(ph, ExitCode);
  TerminateProcess(ph, ExitCode);
end;

end.

GetWindowThreadProcessId - 获取指定窗口的进程 ID 或线程 ID

//声明:
GetWindowThreadProcessId(
  hWnd: HWND;                  {指定窗口句柄}
  lpdwProcessId: Pointer = nil {返回进程 ID 的指针}
): DWORD;                      {返回线程 ID}


//举例:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  c: Cardinal;
begin
  GetWindowThreadProcessId(Handle, @c);
  ShowMessage(IntToStr(c));                   {2792; 随机的}
  {在本例中相同于 GetCurrentProcessID 的结果}
  c := GetCurrentProcessID;
  ShowMessage(IntToStr(c));                   {2792}

  c := GetWindowThreadProcessId(Handle, nil);
  ShowMessage(IntToStr(c));                   {2748}
  {在本例中相同于 GetCurrentThreadID 的结果}
  c := GetCurrentThreadID;
  ShowMessage(IntToStr(c));                   {2748}
end;

end.

GetCurrentThread、GetCurrentThreadId、GetCurrentProcess、GetCurrentProcessId

{返回当前线程的虚拟句柄}
GetCurrentThread: THandle;

{返回当前线程 ID}
GetCurrentThreadId: DWORD;

{返回当前进程的虚拟句柄}
GetCurrentProcess: THandle;

{返回当前进程 ID}
GetCurrentProcessId: DWORD;

提示:
ID 是系统唯一的标识.
所谓虚拟句柄, 就是该句柄只在调用进程的进程中有效, 也不能被继承;
如果用于其他进程需要用 DuplicateHandle 复制句柄;
GetCurrentProcess 返回的虚拟句柄可以通过 OpenProcess 创建一个真实的句柄.

举例:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.Cells[0,0] := '当前线程虚拟句柄: ';
  StringGrid1.Cells[0,1] := '当前线程 ID: ';
  StringGrid1.Cells[0,2] := '当前进程虚拟句柄: ';
  StringGrid1.Cells[0,3] := '当前进程 ID: ';

  StringGrid1.Cells[1,0] := IntToStr(GetCurrentThread);
  StringGrid1.Cells[1,1] := IntToStr(GetCurrentThreadID);
  StringGrid1.Cells[1,2] := IntToStr(GetCurrentProcess);
  StringGrid1.Cells[1,3] := IntToStr(GetCurrentProcessId);

  {下面是显示格式的调整}
  StringGrid1.Align := alClient;
  StringGrid1.FixedRows := 0;
  StringGrid1.RowCount := 4;
  StringGrid1.ColCount := 2;
  StringGrid1.ColWidths[0] := StringGrid1.Canvas.TextWidth(StringGrid1.Cells[0,0]) + 4;
  StringGrid1.ColWidths[1] := StringGrid1.Canvas.TextWidth(StringGrid1.Cells[0,1]) + 4;
end;

end.


 
//效果图: 

LoadLibrary、FreeLibrary - 载入与载卸模块

 

//声明:
LoadLibrary(           {将可执行模块映射到调用进程的地址空间}
  lpLibFileName: PChar {DLL 或 EXE 文件名; 如没指定路径会按以下顺序查找: 程序目录/当前目录/System32/Windows/PATH环境变量}
): HMODULE;            {返回模块句柄}

FreeLibrary(
  hLibModule: HMODULE {模块句柄}
): BOOL;

ShellExecute - 打开外部程序或文件

ShellExecute(
  hWnd: HWND;        {指定父窗口句柄}
  Operation: PChar;  {指定动作, 譬如: open、print}
  FileName: PChar;   {指定要打开的文件或程序}
  Parameters: PChar; {给要打开的程序指定参数; 如果打开的是文件这里应该是 nil}
  Directory: PChar;  {缺省目录}
  ShowCmd: Integer   {打开选项}
): HINST;            {执行成功会返回应用程序句柄; 如果这个值 <= 32, 表示执行错误}

//返回值可能的错误有:
                       = 0   {内存不足}
ERROR_FILE_NOT_FOUND   = 2;  {文件名错误}
ERROR_PATH_NOT_FOUND   = 3;  {路径名错误}
ERROR_BAD_FORMAT       = 11; {EXE 文件无效}
SE_ERR_SHARE           = 26; {发生共享错误}
SE_ERR_ASSOCINCOMPLETE = 27; {文件名不完全或无效}
SE_ERR_DDETIMEOUT      = 28; {超时}
SE_ERR_DDEFAIL         = 29; {DDE 事务失败}
SE_ERR_DDEBUSY         = 30; {正在处理其他 DDE 事务而不能完成该 DDE 事务}
SE_ERR_NOASSOC         = 31; {没有相关联的应用程序}

//ShowCmd 参数可选值:
SW_HIDE            = 0;  {隐藏}
SW_SHOWNORMAL      = 1;  {用最近的大小和位置显示, 激活}
SW_NORMAL          = 1;  {同 SW_SHOWNORMAL}
SW_SHOWMINIMIZED   = 2;  {最小化, 激活}
SW_SHOWMAXIMIZED   = 3;  {最大化, 激活}
SW_MAXIMIZE        = 3;  {同 SW_SHOWMAXIMIZED}
SW_SHOWNOACTIVATE  = 4;  {用最近的大小和位置显示, 不激活}
SW_SHOW            = 5;  {同 SW_SHOWNORMAL}
SW_MINIMIZE        = 6;  {最小化, 不激活}
SW_SHOWMINNOACTIVE = 7;  {同 SW_MINIMIZE}
SW_SHOWNA          = 8;  {同 SW_SHOWNOACTIVATE}
SW_RESTORE         = 9;  {同 SW_SHOWNORMAL}
SW_SHOWDEFAULT     = 10; {同 SW_SHOWNORMAL}
SW_MAX             = 10; {同 SW_SHOWNORMAL}

WinExec - 运行外部程序

//声明
WinExec(
  lpCmdLine: LPCSTR; {文件名和参数; 如没指定路径会按以下顺序查找: 程序目录/当前目录/System32/Windows/PATH环境变量}
  uCmdShow: UINT     {启动选项}
): UINT;

//返回值:
大于 31                    {调用成功}
等于 0                     {内存不足}
ERROR_FILE_NOT_FOUND = 2;  {文件名错误}
ERROR_PATH_NOT_FOUND = 3;  {路径名错误}
ERROR_BAD_FORMAT     = 11; {EXE 文件无效}

//uCmdShow 参数可选值:
SW_HIDE            = 0; {隐藏, 并且任务栏也没有最小化图标}
SW_SHOWNORMAL      = 1; {用最近的大小和位置显示, 激活}
SW_NORMAL          = 1; {同 SW_SHOWNORMAL}
SW_SHOWMINIMIZED   = 2; {最小化, 激活}
SW_SHOWMAXIMIZED   = 3; {最大化, 激活}
SW_MAXIMIZE        = 3; {同 SW_SHOWMAXIMIZED}
SW_SHOWNOACTIVATE  = 4; {用最近的大小和位置显示, 不激活}
SW_SHOW            = 5; {同 SW_SHOWNORMAL}
SW_MINIMIZE        = 6; {最小化, 不激活}
SW_SHOWMINNOACTIVE = 7; {同 SW_MINIMIZE}
SW_SHOWNA          = 8; {同 SW_SHOWNOACTIVATE}
SW_RESTORE         = 9; {同 SW_SHOWNORMAL}
SW_SHOWDEFAULT     = 10; {同 SW_SHOWNORMAL}
SW_MAX             = 10; {同 SW_SHOWNORMAL}


//举例, 启动记事本:
procedure TForm1.Button1Click(Sender: TObject);
begin
  WinExec('notepad.exe', SW_SHOWNORMAL);
end;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值