안녕하세여.
매번 보기만 하다가 처음 질문 올리네여..^^;;;
시스템쪽으로는 까막눈이라..-_-;;;
제가 하고싶은거는 델파이로 만든 프로그램을 돌렸을때
프로세스가 생성되었는지 확인하고 싶구여..
또 그 프로세스가 메모리는 얼마나 차지하고 있는지 보고 싶습니다.
한마디로 윈도 작업관리자에 나오는 이름, PID, 메모리 를
제가 만든 프로그램에서 보고 싶은데요
어떻게 해야할지 막막합니다...
게시판 검색을 해보니 memorystatus 라는게 있던데요
이건 윈도 전체 메모리밖에 안나오는거 같더군여..아닌가.-_-a;;;
어떤 API 가 있나여? 아님 다른걸 활용해야 하나여?
고수님들의 조언부탁드립니당
올립니다
PID 같은것은 아래데로 하면 되는데 문제는 점유한 메모리입니다
NT 계열은 레지스트리에서 찾을 수 있는데 문제는 95 계열입니다
아직 95계열은 자료를 보지 못해서 답변을 드릴 수 없습니다
혹시 나중에라도 구하시면 저좀 주세요...^^
<Windows 95 계열에서 프로세스 처리>
기본적으로 Toolhelp32 (Unit TlHelp32) 가 제공됩니다
Toolhelp32 는 현재 실행중인 프로세스 리스트의 정보를 제공하는데
현재 실행중인 프로세스의 파일명, 프로세스 ID, 각 쓰레드 ID 등을
얻을 수 있으며 threadID 를 가지고 EnumThreadWindows() 함수를 사용하시면
원도우 핸들을 구할 수 있습니다
반대로 원도우 핸들을 가지고 GetWindowThreadProcessID() 함수를 사용하시면
프로세스와 쓰레도 ID 를 구할 수 있습니다
(예제) - 현재 실행된 프로세스중 선택한 프로세스 종료시키기
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, TlHelp32;
type
TForm1 = class(TForm)
ListBox1: TListBox;
B_Search: TButton;
B_Terminate: TButton;
procedure B_SearchClick(Sender: TObject);
procedure B_TerminateClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
// kernel32.dll을 사용하여 현재 떠있는 process를 읽어온다
procedure Process32List(Slist: TStrings);
var
Process32: TProcessEntry32;
SHandle: THandle; // the handle of the Windows object
Next: BOOL;
begin
Process32.dwSize := SizeOf(TProcessEntry32);
SHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Process32First(SHandle, Process32) then
begin
// 실행화일명과 process object 저장
Slist.AddObject(Process32.szExeFile, TObject(Process32.th32ProcessID));
repeat
Next := Process32Next(SHandle, Process32);
if Next then
Slist.AddObject(Process32.szExeFile, TObject(Process32.th32ProcessID));
until not Next;
end;
CloseHandle(SHandle); // closes an open object handle
end;
procedure TForm1.B_SearchClick(Sender: TObject);
begin
// 현재 실행중인 process를 검색
ListBox1.Items.Clear;
Process32List(ListBox1.Items);
end;
procedure TForm1.B_TerminateClick(Sender: TObject);
var
hProcess: THandle;
ProcId: DWORD;
TermSucc: BOOL;
begin
// 현재 실행중인 process를 kill
if ListBox1.ItemIndex < 0 then System.Exit;
ProcId := DWORD(ListBox1.Items.Objects[ListBox1.ItemIndex]);
// 존재하는 process object의 handle을 return한다
hProcess := OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcId);
if hProcess = NULL then
ShowMessage('OpenProcess error !');
// 명시한 process를 강제 종료시킨다
TermSucc := TerminateProcess(hProcess, 0);
if TermSucc = FALSE then
ShowMessage('TerminateProcess error !')
else
ShowMessage(Format('Process# %x terminated successfully !', [ProcId]));
end;
end.
<Windows NT 계열에서 프로세스 처리>
Windows 95 에서 제공하는 Toolhelp32 (Unit TlHelp32)는 NT 에서 사용할 수
없습니다
소문으로는 NT5.0 에 Toolhelp32 를 넣는다고는 하는데...
NT에서는 두가지 방법으로 프로세스 정보를 구할 수 있습니다
첫째는 레지스트리의 HKEY_PERFORMANCE_DATA 섹션을 읽는 방법인데
이것은 동적인 레지스트리라 regedit.exe 로는 볼 수 없고
그것에 맞는 레지스트리 API 를 사용해서 접근할 수 있습니다
제가 개인적으로 NT에서 프로세스 관리 프로그램을 만들때 처음에
이 방법으로 했었는데 정보를 읽는 속도가 너무 느렸습니다
이 방법보다는 아래 PSAPI.DLL 을 사용하는것을 추천합니다
두번째 방법은 PSAPI.DLL 을 이용하는 방법입니다
PSAPI.DLL 는 공식적으로 문서화 되어있지 않으며 PSAPI.DLL 이 시스템
디렉토리에 없는 NT 버전(서비스팩)도 있습니다
아래 사이트에 보시면 관련 콤포넌트와 PSAPI.DLL 이 있습니다
http://www.wilsonc.demon.co.uk/delphi.htm <-- 추천
http://www.santronics.com
http://members.tripod.com/~aldyn/ <-- HKEY_PERFORMANCE_DATA 읽기 방식
그리고 아래 psapi.pas 는 psapi.dll 을 사용하기 위한 인터페이스입니다
unit psapi;
{$WEAKPACKAGEUNIT}
interface
uses Windows;
type
PHInst = ^HInst;
TModuleInfo = record
lpBaseOfDll : pointer;
SizeOfImage : Integer;
EntryPoint : pointer
end;
TPSAPIWsWatchInformation = record
FaultingPc : pointer;
FaultingVa : pointer
end;
TProcessMemoryCounters = record
cb : Integer;
PageFaultCount : Integer;
PeakWorkingSetSize : Integer;
WorkingSetSize : Integer;
QuotaPeakPagedPoolUsage : Integer;
QuotaPagedPoolUsage : Integer;
QuotaPeakNonPagedPoolUsage : Integer;
QuotaNonPagedPoolUsage : Integer;
PagefileUsage : Integer;
PeakPagefileUsage : Integer
end;
function EnumProcesses (pidList : PInteger; cb : Integer; var cbNeeded
: Integer): boolean; stdcall;
function EnumProcessModules (hProcess : THandle; moduleList : PHInst;
cb : Integer; var cbNeeded : Integer) : boolean; stdcall;
function GetModuleBaseName (hProcess : THandle; module : HInst;
BaseName : Pchar; size : Integer) : Integer; stdcall;
function GetModuleFileNameEx (hProcess : THandle; module : HInst;
FileName : PChar; size : Integer) : Integer; stdcall;
function GetModuleInformation(hProcess : THandle; module : HInst; var
info : TModuleInfo; size : Integer) : boolean; stdcall;
function EmptyWorkingSet (hProcess : THandle) : boolean; stdcall;
function QueryWorkingSet (hProcess : THandle; var pv; size : Integer) :
boolean; stdcall;
function InitializeProcessForWsWatch (hProcess : THandle) : boolean;
stdcall;
function GetWsChanges (hProcess : THandle; var WatchInfo :
TPSAPIWsWatchInformation; size : Integer) : boolean; stdcall;
function GetMappedFileName (hProcess : THandle; pv : pointer; FileName
: PChar; size : Integer) : Integer; stdcall;
function EnumDeviceDrivers (var ImageBase : Integer; cb : Integer; var
cbNeeded : Integer) : boolean; stdcall;
function GetDeviceDriverBaseName (ImageBase : Integer; BaseName :
PChar; size : Integer) : Integer; stdcall;
function GetDeviceDriverFileName (ImageBase : Integer; FileName :
PChar; size : Integer) : Integer; stdcall;
function GetProcessMemoryInfo (hProcess : THandle; var
ProcessMemoryCounters : TProcessMemoryCounters; size : Integer) :
boolean; stdcall;
implementation
const psapidll = 'psapi.dll';
function EnumProcesses; external psapidll;
function EnumProcessModules; external psapidll;
function GetModuleBaseName; external psapidll name
'GetModuleBaseNameA';
function GetModuleFileNameEx; external psapidll name
'GetModuleFileNameExA';
function GetModuleInformation; external psapidll;
function EmptyWorkingSet; external psapidll;
function QueryWorkingSet; external psapidll;
function InitializeProcessForWsWatch; external psapidll;
function GetWsChanges; external psapidll;
function GetMappedFileName; external psapidll name
'GetMappedFileNameA';
function EnumDeviceDrivers; external psapidll;
function GetDeviceDriverBaseName; external psapidll name
'GetDeviceDriverBaseNameA';
function GetDeviceDriverFileName; external psapidll name
'GetDeviceDriverFileNameA';
function GetProcessMemoryInfo; external psapidll;
end.
=====================================================================================
There is, it is called PSAPI.DLL, is virtually undocumented and not part of
the standard NT installation. It comes with the Win32 SDK and is
redistributable. I have an import unit for it, which i'll append. Note that
the usage is very different from Toolhelp32. If you want to write a program
that will both work on Win95 and NT you need to write import units for
Toolhelp32 and PSAPI that do not use external statements but dynamic loading
via LoadLibrary/GetProcAddress. These units need to check the current
platform (see Win32Version in Sysutils) and only try to load the functions
if on the right platform. Calling the functions also needs to be made
platform-specific. NT 5 will have Toolhelp32, the NT development team seems
to have caved in to constant pressure from the developers <g>.
NT 4: PSAPI.DLL. Search the newsgroup via forumsearch.borland.com:88, an
import unit has been posted several times. Colin Wilson may have it on his
website, too: http://www.wilsonc.demon.co.uk/delphi.htm
There is currently no common method for all Win32 platforms, which makes
using this kind of functionality a major pain in the anatomy. Rumour has it
that NT 5.0 will include Toolhelp32...
------------------------------------------ NT process -----------------------------------------------
There are two ways of doing it in NT.
The old way is to use the information stored in the
HKEY_PERFORMANCE_DATA registry key.
The new way is to use the functions in NSAPI.DLL, which comes with the
SDK, and is distributable.
------------------------------------------ NT process -----------------------------------------------
On Nov 06, 1997 08:26am, MCLAI@BINNIE.DEMON.CO.UK (MIKE LAI) wrote to ALL:
ML> Under Win31 I was able to find out what tasks were running by using
ML> TTaskEntry and calling TaskFirst and TaskNext. Under Win95 I could
ML> acheive the same using Process32First and Process32Next. Now I want to
ML> do the same under WinNT. Does anybody know how to do ?
Get perf32.zip in the delphi section at http://www.santronics.com
Its a component which works for both 95/NT.
Hector Santos/Santronics Software
------------------------------------------ NT process -----------------------------------------------
http://www.wilsonc.demon.co.uk/delphi.htm#NT Specific Components
------------------------------------------ NT process -----------------------------------------------
In article <6cusr4$l4r2@forums.borland.com>, Thomas Malone wrote:
There is, it is called PSAPI.DLL, is virtually undocumented and not part of
the standard NT installation. It comes with the Win32 SDK and is
redistributable. I have an import unit for it, which i'll append. Note that
the usage is very different from Toolhelp32. If you want to write a program
that will both work on Win95 and NT you need to write import units for
Toolhelp32 and PSAPI that do not use external statements but dynamic loading
via LoadLibrary/GetProcAddress. These units need to check the current
platform (see Win32Version in Sysutils) and only try to load the functions
if on the right platform. Calling the functions also needs to be made
platform-specific. NT 5 will have Toolhelp32, the NT development team seems
to have caved in to constant pressure from the developers <g>.
Oh, nearly forgot: PSAPI was described in two articles in Matt Pietreks
"Under the hood" column in The Microsoft Systems Journal, Aug. and Nov. 96.
Peter Below (TeamB) 100113.1101@compuserve.com)
{ Posted by Colin Wilson on borland.public.delphi.winapi }
unit psapi;
{$WEAKPACKAGEUNIT}
interface
uses Windows;
type
PHInst = ^HInst;
TModuleInfo = record
lpBaseOfDll : pointer;
SizeOfImage : Integer;
EntryPoint : pointer
end;
TPSAPIWsWatchInformation = record
FaultingPc : pointer;
FaultingVa : pointer
end;
TProcessMemoryCounters = record
cb : Integer;
PageFaultCount : Integer;
PeakWorkingSetSize : Integer;
WorkingSetSize : Integer;
QuotaPeakPagedPoolUsage : Integer;
QuotaPagedPoolUsage : Integer;
QuotaPeakNonPagedPoolUsage : Integer;
QuotaNonPagedPoolUsage : Integer;
PagefileUsage : Integer;
PeakPagefileUsage : Integer
end;
function EnumProcesses (pidList : PInteger; cb : Integer; var cbNeeded
: Integer): boolean; stdcall;
function EnumProcessModules (hProcess : THandle; moduleList : PHInst;
cb : Integer; var cbNeeded : Integer) : boolean; stdcall;
function GetModuleBaseName (hProcess : THandle; module : HInst;
BaseName : Pchar; size : Integer) : Integer; stdcall;
function GetModuleFileNameEx (hProcess : THandle; module : HInst;
FileName : PChar; size : Integer) : Integer; stdcall;
function GetModuleInformation(hProcess : THandle; module : HInst; var
info : TModuleInfo; size : Integer) : boolean; stdcall;
function EmptyWorkingSet (hProcess : THandle) : boolean; stdcall;
function QueryWorkingSet (hProcess : THandle; var pv; size : Integer) :
boolean; stdcall;
function InitializeProcessForWsWatch (hProcess : THandle) : boolean;
stdcall;
function GetWsChanges (hProcess : THandle; var WatchInfo :
TPSAPIWsWatchInformation; size : Integer) : boolean; stdcall;
function GetMappedFileName (hProcess : THandle; pv : pointer; FileName
: PChar; size : Integer) : Integer; stdcall;
function EnumDeviceDrivers (var ImageBase : Integer; cb : Integer; var
cbNeeded : Integer) : boolean; stdcall;
function GetDeviceDriverBaseName (ImageBase : Integer; BaseName :
PChar; size : Integer) : Integer; stdcall;
function GetDeviceDriverFileName (ImageBase : Integer; FileName :
PChar; size : Integer) : Integer; stdcall;
function GetProcessMemoryInfo (hProcess : THandle; var
ProcessMemoryCounters : TProcessMemoryCounters; size : Integer) :
boolean; stdcall;
implementation
const psapidll = 'psapi.dll';
function EnumProcesses; external psapidll;
function EnumProcessModules; external psapidll;
function GetModuleBaseName; external psapidll name
'GetModuleBaseNameA';
function GetModuleFileNameEx; external psapidll name
'GetModuleFileNameExA';
function GetModuleInformation; external psapidll;
function EmptyWorkingSet; external psapidll;
function QueryWorkingSet; external psapidll;
function InitializeProcessForWsWatch; external psapidll;
function GetWsChanges; external psapidll;
function GetMappedFileName; external psapidll name
'GetMappedFileNameA';
function EnumDeviceDrivers; external psapidll;
function GetDeviceDriverBaseName; external psapidll name
'GetDeviceDriverBaseNameA';
function GetDeviceDriverFileName; external psapidll name
'GetDeviceDriverFileNameA';
function GetProcessMemoryInfo; external psapidll;
end.
------------------------------------------ NT process -----------------------------------------------
You need to have separate routines to handle either platform, but you can
"if..then..else" your way around, so you don't need two programs.
I have some code that tries to load toolhelp, then it tries to load PSAPI.
I call whichever set of functions, accordingly. Here's the portion that
loads the psapi stuff, without bombing:
{Load-up psapi functions (NT)}
hPSAPI_DLL := LoadLibrary('PSAPI.DLL'); // PSAPI(Process Status API)
if (hPSAPI_DLL <> 0)
Then Begin
FuncPtr := GetProcAddress(hPSAPI_DLL, 'GetModuleFileNameExA');
@CallMeGetModuleFileNameEx:= FuncPtr;
FuncPtr := GetProcAddress(hPSAPI_DLL, 'GetModuleBaseNameA');
@CallMeGetModuleBaseName:= FuncPtr;
end
else begin
@CallMeGetModuleFileNameEx := nil;
@CallMeGetModuleBaseName := nil;
end;
Just make sure the functions aren't nil when you go to call them. I require
either the PSAPI or the Toolhelp to have sucessfully loaded - or I abort if
neither loads. I guess that would only happen under NT 3.51
Also, I'd be nowhere without Colin Wilson's unit. Thanks Colin!
Chris
------------------------------------------ NT process -----------------------------------------------
Yeah, and NT3.x too.
At one stage, Microsoft claimed that they would 'never' put the
toolhelp stuff in NT, so it's interesting that they've done it in NT5.
The 'correct' way to get the all important process ID list under NT is
to use the information in the HKEY_PERFORMANCE_DATA section of the
registry. It's a dynamic registry area, so it doesn't show up in
regedit, but you can access it with the registry API functions.
The traditional way (for Microsoft to implement the task manager, for
instance) is to use undocumented functions in kernel32.dll.
Last year, Microsoft included PSAPI.DLL, .H and .LIB in the SDK. They
claimed it was now a supported way to get at this information. It's
quite a small DLL; internally it just makes the 'undocumented' calls,
and the DLL is redistributable with you apps. I've done a D3 interface
unit for it, which floats around this newsgroup. You can probably find
it on dejaview (or whatever it's called). Mail me if you need a copy.
I believe Hector Santos has (had?) a component on his web site which
detects which OS you're using and dynamically loads the correct APIs,
etc.
It's all a bit of a mess at the moment...
Colin
------------------------------------------ NT process -----------------------------------------------
Hmmm...I couldn't find it by searching Microsoft's web site either. Funny
thing is, that's how I found it in the first place, about a month ago. Quite
the search engine they have there, especially since the stuff is still
there. Try this:
1 - Go to http://www.microsoft.com/msdn
2 - If you're not a member, then sign up. This allows you access to all the
content.
3 - Click on the MSDN Library Online option at the left.
4 - Click the Library Online tab (this opens a tree of all the
documentation).
5 - Go to:
SDK documentation
-> Windows Base Services
-> Windows NT Features
-> Performance Status Helper
There you should find information on the functions I described and a bunch
of others you might find useful.
Michael
------------------------------------------ NT process -----------------------------------------------
Under NT you either use the HKEY_PERFORMANCE_DATA to look up the PID
you got from GetWindowThreadProcessID (very complicated), or you use
PSAPI.DLL, which is a redistributable Microsoft DLL (it comes with
MSDN, the SDK, etc.)
It includes such gems as EnumProcesses, EnumProcessModules,
GetModuleBaseName, GetModuleFileNameEx, etc.
Seeing as it's redistributable I can mail you an application that uses
it (and the DLL too), plus the Delphi interface library for the DLL.
------------------------------------------ NT process -----------------------------------------------
Use the functions in Unit TlHelp32 (Toolhelp32 for Win95). They are specific for
Win95 and will not work on NT, but you can use them to enumerate all running
processes, get their filenames, process IDs, enumerate the threads of each, getting
the threadIDs. From threadIDs you can get to window handles using EnumThreadWindows.
From a window handle you get to the process and thead IDs using
GetWindowThreadProcessID.
------------------------------------------ GetWindowText -----------------------------------------------
if you want to get the title of your application use property:
function GetTitle(WinHandle : HWND) : string;
var
TitleLn : integer;
begin
Result := '';
TitleLn := GetWindowTextLength(WinHandle);
if TitleLn > 0 then
begin
inc(TitleLn); // increase title length, because GetWindowText
//adds null carachter at the end of string
SetLength(Result, TitleLn);
GetWindowText(WinHandle, PChar(Result), TitleLn);
end;
end;