关于XP下获取正在运行程序的路径(100分)

  • 主题发起人 主题发起人 ivan
  • 开始时间 开始时间
I

ivan

Unregistered / Unconfirmed
GUEST, unregistred user!
如果和98一样,用Toolhelp的函数获得的只是程序的名字,而没有路径,谁有办法搞定?
如果可能的话,请给出所有平台的完全解决方案。。。
 
uses tlhelp32;
procedure TForm1.Button1Click(Sender: TObject);
var
pe:PROCESSENTRY32;
me:MODULEENTRY32;
hp,hm:Thandle;
b,b1:boolean;
begin
hp:=CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS,0);
pe.dwSize:=SizeOf(pe);
b:=Process32First(hp,pe);
while b do
begin
hm:=CreateToolHelp32SnapShot(TH32CS_SNAPModule,pe.th32ProcessID);
me.dwSize:=sizeof(ModuleEntry32);
if Module32First(hm,me) then
begin
b1:=Module32First(hm,me);
while b1 do
begin
if me.th32ModuleID=pe.th32ModuleID then
listbox1.Items.Add(me.szExePath);
b1:=Module32Next(hm,me);
end;
end;
b:=Process32Next(hp,pe);
end;

end;





--------------------------------------------------------------------------------
toolhelp api 在 nt 上不支持
下面的可以在 nt 上运行
如果要copy到其他机上运行,要顺便拷贝 psapi.dll(这个dll安装delphi或者c++ builder后就有了)

#include "psapi.hpp"

假使process id是 pid 的话:

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,pid);
if( NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if( EnumProcessModules( hProcess, &hMod, sizeof( hMod ), &cbNeeded ) )
{
char buf[MAX_PATH+1]="";
if(GetModuleBaseName( hProcess, hMod,buf,sizeof buf)>0)
//
// buf放的就是名字
//
}
CloseHandle(hProcess);
}



--------------------------------------------------------------------------------
找出所有进程的 process id:

下面的程序也是可以在 nt 上运行:

下面的程序也是需要 psapi.dll

#include "psapi.hpp"

DWORD pid[1000];
DWORD ret_id=0;
if(!EnumProcesses(pid,sizeof pid,&ret_id))
//返回0,就是失败了

成功的话返回 非 0 值

ret_id是返回的字节数,注意不是id的个数,
比如返回 1 个id,实际上ret_id等于4,(表示4个字节)
ret_id/4 才是 返回 的id 的个数

返回的id放在 数组 pid
大小要大于 id 可能的最大数才找的全,上面的例子是可以找1000个,足够了,
如果嫌大,200个就可以了



xp同nt
 
其实这2段程序我都看过,helptool的那个部分我在XP下写了写,
结果可以用,但是不能返回程序的路径,而psapi.dll我没试,估计应该可以成功。
有没有人有已经写好了的,自动判断操作系统,然后选择方法获取路径的单元?
to wbtvc:
本来想直接接受你的答案的,但是我懒了一下,不想自己写那么多代码了,
所以想找一份现成的,而且psapi.dll的支持你用的c++来写,我不太会翻译。
不好意思了。。。
 
你也真是的,这么懒呀,唉,我还不是程序员,都比你好点。
psapi.dll是一定支持xp的,而且据我所知现在在xp、nt、2000下只能用这个方法。
算了,给你贴一段delphi的:(还有我想说:我因为学历低,到现在还没找到个
IT业的工作,只好在家里自学,不知道你是不是程序员,如果是的话,我真觉得
不公平呀)
unit WNTInfo;

interface

uses InfoInt, Windows, Classes, ComCtrls, Controls;

type
TWinNTInfo = class(Tobject)
private
FProcList: array of DWORD;
FDrvlist: array of Pointer;
FWinIcon: HICON;
procedure FillProcesses(ListView: TListView; ImageList: TImageList);
procedure FillDrivers(ListView: TListView; ImageList: TImageList);
procedure Refresh;
public
constructor Create;
destructor Destroy; override;
procedure FillProcessInfoList(ListView: TListView;
ImageList: TImageList);
procedure ShowProcessProperties(Cookie: Pointer);
end;

implementation

uses SysUtils, PSAPI, ShellAPI, CommCtrl, DetailNT;

const
SFailMessage = 'Failed to enumerate processes or drivers. Make sure '+
'PSAPI.DLL is installed on your system.';
SDrvName = 'driver';
SProcname = 'process';
ProcessInfoCaptions: array[0..4] of string = (
'Name', 'Type', 'ID', 'Handle', 'Priority');

function GetPriorityClassString(PriorityClass: Integer): string;
begin
case PriorityClass of
HIGH_PRIORITY_CLASS: Result := 'High';
IDLE_PRIORITY_CLASS: Result := 'Idle';
NORMAL_PRIORITY_CLASS: Result := 'Normal';
REALTIME_PRIORITY_CLASS: Result := 'Realtime';
else
Result := Format('Unknown ($%x)', [PriorityClass]);
end;
end;

{ TWinNTInfo }

constructor TWinNTInfo.Create;
begin
FWinIcon := LoadImage(0, IDI_WINLOGO, IMAGE_ICON, LR_DEFAULTSIZE,
LR_DEFAULTSIZE, LR_DEFAULTSIZE or LR_DEFAULTCOLOR or LR_SHARED);
end;

destructor TWinNTInfo.Destroy;
begin
DestroyIcon(FWinIcon);
inherited Destroy;
end;

procedure TWinNTInfo.FillDrivers(ListView: TListView;
ImageList: TImageList);
var
I: Integer;
DrvName: array[0..MAX_PATH] of char;
begin
for I := Low(FDrvList) to High(FDrvList) do
if GetDeviceDriverFileName(FDrvList, DrvName,
SizeOf(DrvName)) > 0 then
with ListView.Items.Add do
begin
Caption := DrvName;
SubItems.Add(SDrvName);
SubItems.Add('$' + IntToHex(Integer(FDrvList), 8));
end;
end;

procedure TWinNTInfo.FillProcesses(ListView: TListView;
ImageList: TImageList);
var
I: Integer;
Count: DWORD;
ProcHand: THandle;
ModHand: HMODULE;
HAppIcon: HICON;
ModName: array[0..MAX_PATH] of char;
begin
for I := Low(FProcList) to High(FProcList) do
begin
ProcHand := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
False, FProcList);
if ProcHand > 0 then
try
EnumProcessModules(Prochand, @ModHand, 1, Count);
if GetModuleFileNameEx(Prochand, ModHand, ModName,
SizeOf(ModName)) > 0 then
begin
HAppIcon := ExtractIcon(HInstance, ModName, 0);
try
if HAppIcon = 0 then HAppIcon := FWinIcon;
with ListView.Items.Add, SubItems do
begin
Caption := ModName; // file name
Data := Pointer(FProcList); // save ID
Add(SProcName); // "process"
Add(IntToStr(FProcList)); // process ID
Add('$' + IntToHex(ProcHand, 8)); // process handle
// priority class
Add(GetPriorityClassString(GetPriorityClass(ProcHand)));
// icon
if ImageList <> nil then
ImageIndex := ImageList_AddIcon(ImageList.Handle,
HAppIcon);
end;
finally
if HAppIcon <> FWinIcon then DestroyIcon(HAppIcon);
end;
end;
finally
CloseHandle(ProcHand);
end;
end;
end;

procedure TWinNTInfo.FillProcessInfoList(ListView: TListView;
ImageList: TImageList);
var
I: Integer;
begin
Refresh;
ListView.Columns.Clear;
ListView.Items.Clear;
for I := Low(ProcessInfoCaptions) to High(ProcessInfoCaptions) do
with ListView.Columns.Add do
begin
if I = 0 then Width := 285
else Width := 75;
Caption := ProcessInfoCaptions;
end;
FillProcesses(ListView, ImageList); // Add processes to listview
FillDrivers(ListView, ImageList); // Add device drivers to listview
end;

procedure TWinNTInfo.Refresh;
var
Count: DWORD;
BigArray: array[0..$3FFF - 1] of DWORD;
begin
// Get array of process IDs
if not EnumProcesses(@BigArray, SizeOf(BigArray), Count) then
raise Exception.Create(SFailMessage);
SetLength(FProcList, Count div SizeOf(DWORD));
Move(BigArray, FProcList[0], Count);
// Get array of Driver addresses
if not EnumDeviceDrivers(@BigArray, SizeOf(BigArray), Count) then
raise Exception.Create(SFailMessage);
SetLength(FDrvList, Count div SizeOf(DWORD));
Move(BigArray, FDrvList[0], Count);
end;

procedure TWinNTInfo.ShowProcessProperties(Cookie: Pointer);
begin
ShowProcessDetails(DWORD(Cookie));
end;

end.

上述代码摘抄于delphi5开发人员指南
 
呵呵,谢谢了啦,虽然我还没调试,但是就冲你的帮助,也要把分给你
主要这两天事情太多了,忙不过来。。。
感谢呀。。。
 
感谢呀。。。。
 
好像代码里有个问题,记不清了,如果你调试不行的话,再来这里吧
 
后退
顶部