Autor Beitrag
crowley
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 406

Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
BeitragVerfasst: Di 15.05.07 14:38 
Servus und Hallo,

wie kann ich die Größe des virtuellen Speichers eines Prozesses bestimmen? Um diesen Wert für die eigene (aktuell laufende) Anwendung zu bestimmen kann ich diesen Wert mit

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function CalculateVirtualMemoryUsed: Int64;
var
  loc_mem : TMemoryStatus;
begin
  {Set the structure size}
  loc_mem.dwLength := SizeOf(loc_mem);
  {Get the memory status}
  GlobalMemoryStatus(loc_mem);
  {The result is the total address space less the free address space}
  Result := (loc_mem.dwTotalVirtual - loc_mem.dwAvailVirtual);
end;


ermitteln.

Das Problem ist, dass ich diesen Wert nicht für andere Prozesse abfragen kann... Ich habe schon - wenig erfolgreich - mit GetProcessMemoryInfo experimentiert, aber dort bekomme ich nicht den gewünschten Wert... oder kann man den dort irgendwie als Summe aus PrivateBytes/WorkingSetSize und und und berechnen?

Vielen Dank,

C.
moddin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75

WinXP Pro
Delphi 7 Enterprise ;-)
BeitragVerfasst: Mo 28.05.07 00:22 
Injeziere einen angepassten Code zur Memoryabfrage mittels CreateRemoteThread/WriteProcessMemory in den anderen prozess und
lese das ergebniss über ReapProcessMemory wieder aus

Brutal,funktioniert aber :P

_________________
Willst du Körper an Körper pressen? Atem spüren? Gerüche wahrnehmen? Verschiedene Stellungen probieren? Rein und raus? Von hinten nach vorne? Ja? Dann nimm den Bus!
crowley Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 406

Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
BeitragVerfasst: Fr 08.06.07 10:37 
Servus und Hallo,

ich habe auch noch eine andere Möglichkeit gefunden:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
  SystemProcessInformation = 5;
  STATUS_INFO_LENGTH_MISMATCH = Integer($C0000004);

type
  UNICODE_STRING = record
    Length: Word;
    MaximumLength: Word;
    Buffer: PWideChar;
  end;
  PUNICODE_STRING = ^UNICODE_STRING;
  TUNICODE_STRING = UNICODE_STRING;

  _SYSTEM_PROCESS_INFORMATION = record
    NextEntryOffset: ULONG;
    NumberOfThreads: ULONG;
    SpareLi1, SpareLi2, SpareLi3: TLargeInteger;
    CreateTime, UserTime, KernelTime: TLargeInteger;
    ImageName: UNICODE_STRING;
    BasePriority: ULONG;
    UniqueProcessId: THandle;
    InheritedFromUniqueProcessId: THandle;
    HandleCount: ULONG;
    SessionId: ULONG;
    SpareUl3: ULONG;
    PeekVirtualSize: ULONG;
    VirtualSize: ULONG;
    PageFaultCount: ULONG;
    PeakWorkingSetSize: ULONG;
    WorkingSetSize: ULONG;
    QuotaPeakPagedPoolUsage: ULONG;
    QuotaPagedPoolUsage: ULONG;
    QuotaPeakNonPagedPoolUsage: ULONG;
    QuotaNonPagedPoolUsage: ULONG;
    PagefileUsage: ULONG;
    PeakPagefileUsage: ULONG;
    PrivatePageCount: ULONG;
  end;
  TSystem_Process_Information = _SYSTEM_PROCESS_INFORMATION;
  PSystem_Process_Information = ^TSystem_Process_Information;

{
********************************************************************************
*                        Internal Helper Functions                             *
********************************************************************************
}

function NtQuerySystemInformation(SystemInformationClass: Cardinal;
                                  SystemInformation: Pointer;
                                  Length: ULONG;
                                  ResultLength: PULONG): Integer; stdcall; external 'ntdll.dll';

function GetProcessVirtualMemorySize(const aProcessId: Cardinal) : Int64;
const
  BUF_SIZE = $10000;
var
  ProcListBuffer: PChar;
  ProcessInfo: PSYSTEM_PROCESS_INFORMATION;
  ProcOffset: ULONG;
  BufSize: Cardinal;
  Status: Integer;
  loc_found: Boolean;
begin
  Result := 0;

  ProcListBuffer := nil;
  try
    // capture the process list
    BufSize := BUF_SIZE;
    repeat
      GetMem(ProcListBuffer, BufSize);
      if ProcListBuffer = nil then begin
        Exit;
      end;

      Status := NtQuerySystemInformation(
                                         SystemProcessInformation,
                                         ProcListBuffer,
                                         BufSize,
                                         nil
                                        );
      if Status = STATUS_INFO_LENGTH_MISMATCH then begin
        // Buffer was too small, increase the buffer size and try again
        FreeMem(ProcListBuffer);
        Inc(BufSize, BUF_SIZE);
      end
      else if Status < 0 then begin
        // Another error occured
        Exit;
      end;
    until Status >= 0;

    loc_found := False;
    // we got the entire process list now, extract all PIDs
    ProcOffset := 0;
    ProcessInfo := PSYSTEM_PROCESS_INFORMATION(ProcListBuffer);
    repeat
      ProcessInfo := PSYSTEM_PROCESS_INFORMATION(Cardinal(ProcessInfo) + ProcOffset);
      ProcOffset := ProcessInfo^.NextEntryOffset;

      if ProcessInfo^.UniqueProcessId = aProcessId then begin
        Result := ProcessInfo^.VirtualSize;
        loc_found := True;
      end;
    until (ProcOffset = 0) or loc_found;
  finally
    if Assigned(ProcListBuffer) then
      FreeMem(ProcListBuffer);
  end;
end;


Damit funktioniert es - entsprechende Berechtigungen vorausgesetzt - hervorragend ;)

C.