Come posso ottenere l'elenco dei file aperti da un'applicazione, utilizzando Delphi? Ad esempio quali file vengono aperti da winword.exeDelphi: ottieni i file aperti da un'applicazione
7
A
risposta
12
Utilizzando la funzione API nativa NtQuerySystemInformation è possibile elencare tutti gli handle aperti da tutti i processi.
provare questo esempio
program ListAllHandles;
{$APPTYPE CONSOLE}
uses
PSApi,
Windows,
SysUtils;
const
SystemHandleInformation = $10;
STATUS_SUCCESS = $00000000;
STATUS_BUFFER_OVERFLOW = $80000005;
STATUS_INFO_LENGTH_MISMATCH = $C0000004;
DefaulBUFFERSIZE = $100000;
type
OBJECT_INFORMATION_CLASS = (ObjectBasicInformation,ObjectNameInformation,ObjectTypeInformation,ObjectAllTypesInformation,ObjectHandleInformation);
SYSTEM_HANDLE=packed record
uIdProcess:ULONG;
ObjectType:UCHAR;
Flags :UCHAR;
Handle :Word;
pObject :Pointer;
GrantedAccess:ACCESS_MASK;
end;
PSYSTEM_HANDLE = ^SYSTEM_HANDLE;
SYSTEM_HANDLE_ARRAY = Array[0..0] of SYSTEM_HANDLE;
PSYSTEM_HANDLE_ARRAY= ^SYSTEM_HANDLE_ARRAY;
SYSTEM_HANDLE_INFORMATION=packed record
uCount:ULONG;
Handles:SYSTEM_HANDLE_ARRAY;
end;
PSYSTEM_HANDLE_INFORMATION=^SYSTEM_HANDLE_INFORMATION;
TNtQuerySystemInformation=function (SystemInformationClass:DWORD; SystemInformation:pointer; SystemInformationLength:DWORD; ReturnLength:PDWORD):THandle; stdcall;
TNtQueryObject =function (ObjectHandle:cardinal; ObjectInformationClass:OBJECT_INFORMATION_CLASS; ObjectInformation:pointer; Length:ULONG;ResultLength:PDWORD):THandle;stdcall;
UNICODE_STRING=packed record
Length :Word;
MaximumLength:Word;
Buffer :PWideChar;
end;
OBJECT_NAME_INFORMATION=UNICODE_STRING;
POBJECT_NAME_INFORMATION=^OBJECT_NAME_INFORMATION;
Var
NTQueryObject :TNtQueryObject;
NTQuerySystemInformation:TNTQuerySystemInformation;
function GetObjectInfo(hObject:cardinal; objInfoClass:OBJECT_INFORMATION_CLASS):LPWSTR;
var
pObjectInfo:POBJECT_NAME_INFORMATION;
HDummy :THandle;
dwSize :DWORD;
begin
Result:=nil;
dwSize := sizeof(OBJECT_NAME_INFORMATION);
pObjectInfo := AllocMem(dwSize);
HDummy := NTQueryObject(hObject, objInfoClass, pObjectInfo,dwSize, @dwSize);
if((HDummy = STATUS_BUFFER_OVERFLOW) or (HDummy = STATUS_INFO_LENGTH_MISMATCH)) then
begin
FreeMem(pObjectInfo);
pObjectInfo := AllocMem(dwSize);
HDummy := NTQueryObject(hObject, objInfoClass, pObjectInfo,dwSize, @dwSize);
end;
if((HDummy >= STATUS_SUCCESS) and (pObjectInfo.Buffer <> nil)) then
begin
Result := AllocMem(pObjectInfo.Length + sizeof(WCHAR));
CopyMemory(result, pObjectInfo.Buffer, pObjectInfo.Length);
end;
FreeMem(pObjectInfo);
end;
Procedure EnumerateOpenFiles();
var
sDummy : string;
hProcess : THandle;
hObject : THandle;
ResultLength: DWORD;
aBufferSize : DWORD;
aIndex : Integer;
pHandleInfo : PSYSTEM_HANDLE_INFORMATION;
HDummy : THandle;
lpwsName : PWideChar;
lpwsType : PWideChar;
lpszProcess : PAnsiChar;
begin
AbufferSize := DefaulBUFFERSIZE;
pHandleInfo := AllocMem(AbufferSize);
HDummy := NTQuerySystemInformation(DWORD(SystemHandleInformation), pHandleInfo,AbufferSize, @ResultLength); //Get the list of handles
if(HDummy = STATUS_SUCCESS) then //If no error continue
begin
for aIndex:=0 to pHandleInfo^.uCount-1 do //iterate the list
begin
hProcess := OpenProcess(PROCESS_DUP_HANDLE or PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, pHandleInfo.Handles[aIndex].uIdProcess); //open the process to get aditional info
if(hProcess <> INVALID_HANDLE_VALUE) then //Check valid handle
begin
hObject := 0;
if DuplicateHandle(hProcess, pHandleInfo.Handles[aIndex].Handle,GetCurrentProcess(), @hObject, STANDARD_RIGHTS_REQUIRED,FALSE, 0) then //Get a copy of the original handle
begin
lpwsName := GetObjectInfo(hObject, ObjectNameInformation); //Get the filename linked to the handle
if (lpwsName <> nil) then
begin
lpwsType := GetObjectInfo(hObject, ObjectTypeInformation);
lpszProcess := AllocMem(MAX_PATH);
if GetModuleFileNameEx(hProcess, 0,lpszProcess, MAX_PATH)<>0 then //get the name of the process
sDummy:=ExtractFileName(lpszProcess)
else
sDummy:= 'System Process';
Writeln('PID ',pHandleInfo.Handles[aIndex].uIdProcess);
Writeln('Handle ',pHandleInfo.Handles[aIndex].Handle);
Writeln('Process ',sDummy);
Writeln('FileName ',string(lpwsName));
Writeln;
FreeMem(lpwsName);
FreeMem(lpwsType);
FreeMem(lpszProcess);
end;
CloseHandle(hObject);
end;
CloseHandle(hProcess);
end;
end;
end;
FreeMem(pHandleInfo);
end;
begin
try
NTQueryObject := GetProcAddress(GetModuleHandle('NTDLL.DLL'), 'NtQueryObject');
NTQuerySystemInformation := GetProcAddress(GetModuleHandle('NTDLL.DLL'), 'NtQuerySystemInformation');
if (@NTQuerySystemInformation<>nil) and (@NTQuerySystemInformation<>nil) then
EnumerateOpenFiles();
Readln;
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
2
È possibile effettuare il porting walkobjects.cpp o eseguire un command line process that does it for you e analizzare l'output.
1
Ho guardato la pagina di MSDN ... ha detto NtQuerySystemInformation() è un proc interna OS, e che non stiamo consigliabile usarlo:
la funzione NtQuerySystemInformation e le strutture che restituisca sono interna al sistema operativo e soggetti a modifiche da un rilascio di Windows a un altro. Per mantenere la compatibilità della tua applicazione, è meglio usare le funzioni alternate precedentemente citate, .
Problemi correlati
- 1. Delphi Ottieni posizione file
- 2. Salvare i file aperti (sessione) in NetBeans
- 3. gdb: come elencare i file aperti
- 4. Troppi file aperti avviso da elasticsearch
- 5. Git branching mentre i file sono aperti
- 6. Chiudere i file aperti utilizzando C#
- 7. su iOS/iPhone: "Troppi file aperti": è necessario elencare i file aperti (come lsof)
- 8. Sottoprocesso Python: troppi file aperti
- 9. Come tracciare tutti i file aperti da un processo e i suoi processi figli?
- 10. Troppi handle di file aperti
- 11. Nome dei file aperti da un processo nella finestra?
- 12. Chiusura di tutti i file aperti in un processo
- 13. Utilizzando il comando VIM su tutti i file aperti
- 14. php-fpm Troppi file aperti
- 15. Fatal Error - Troppi file aperti
- 16. Esegui file batch da Delphi IDE
- 17. Su Linux: imposta i file aperti massimi su illimitato. Possibile?
- 18. I file vengono aperti nell'area di modifica errata
- 19. Socket accettare - "Troppi file aperti"
- 20. Ottieni tutti i file da VSS per una data specifica?
- 21. Perché ricevo un errore "Troppi file aperti - conversione" da Paperclip?
- 22. Nascondere tutti i moduli aperti
- 23. Come chiudere tutti i file di rete aperti in PowerShell?
- 24. Identificare i file aperti un processo particolare su linux
- 25. Come posso ripristinare tutti i file aperti in modo forzato?
- 26. Come impedire a PyCharm di chiudere automaticamente i file aperti?
- 27. Collegamento per chiudere tutti i file aperti in IntelliJ
- 28. aperti i permessi dei file() non correttamente l'impostazione
- 29. sublime: salva tutti i file aperti/caricati con nomi?
- 30. Come impedire a NetBeans di ricordare i file aperti?
I file di intestazione per l'API nativa sono presenti nel Jedi ApiLib (JwaNative) (Jwa) e nel resto dell'SDK di Windows ciò consente di non dichiararli come sopra. Se il Jedi ApiLib è nuovo per te il nostro blog è probabilmente un buon punto di partenza (http://blog.delphi-jedi.net/) – Remko
Ciao @Remko, conosco il Jedi APILib, questo è solo un semplice esempio del API NtQuerySystemInformation, senza dipendenze. ;) – RRUZ
Ciao RRUZ. Quando eseguo il codice, come risultato ottengo la riga del nome del file: "NomeFile \ BaseNamedObjects \ CTF.Compart.MutexDefaultS-1-5-21-2000478354-606747145-1801674531-500". Mi sto perdendo qualcosa? Sto facendo qualcosa di sbagliato? –