Delphi: obtén los archivos que abre una aplicación

¿Cómo puedo obtener la lista de archivos abiertos por una aplicación, usando Delphi? Por ejemplo, qué archivos abre winword.exe

Mediante la función Native API NtQuerySystemInformation , puede enumerar todos los identificadores abiertos de todos los procesos.

prueba este ejemplo

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. 

Puede portar walkobjects.cpp o ejecutar un proceso de línea de comandos que lo haga por usted y analizar su salida.

Miré la página de MSDN … decía que NtQuerySystemInformation () es un proceso interno del sistema operativo, y que no se recomienda su uso:

La función NtQuerySystemInformation y las estructuras que devuelve son internas del sistema operativo y están sujetas a cambios de una versión de Windows a otra. Para mantener la compatibilidad de su aplicación, es mejor utilizar las funciones alternativas mencionadas anteriormente en su lugar.