在 Windows 2000 及更高版本上,您可以使用NetFileEnum API:
program test;
{$APPTYPE CONSOLE}
uses
Windows,
Classes,
SysUtils;
type
PFileInfo3 = ^TFileInfo3;
TFileInfo3 = record
fi3_id: DWORD;
fi3_permissions: DWORD;
fi3_num_locks: DWORD;
fi3_pathname: PWideChar;
fi3_username: PWideChar;
end;
TNetFileEnumCallback = function(const FileInfo: TFileInfo3; Data: Pointer): Boolean;
const
netapi = 'netapi32.dll';
function NetApiBufferFree(Buffer: Pointer): DWORD; stdcall; external netapi;
function NetFileEnum(servername: PWideChar; basepath: PWideChar; username: PWideChar; level: DWORD; var bufptr: Pointer;
prefmaxlen: DWORD; var entriesread: DWORD; var totalentries: DWORD; resume_handle: PDWORD): DWORD; stdcall;
external netapi;
procedure EnumNetFileUsers(const LocalPath: WideString; Callback: TNetFileEnumCallback; Data: Pointer = nil);
const
EntryCount = 32;
var
NetResult, EntriesRead, TotalEntries, ResumeHandle: Cardinal;
Buf: Pointer;
P: PFileInfo3;
I: Integer;
begin
EntriesRead := 0;
TotalEntries := 0;
ResumeHandle := 0;
repeat
NetResult := NetFileEnum(nil, PWideChar(LocalPath), nil, 3, Buf, EntryCount * SizeOf(TFileInfo3), EntriesRead,
TotalEntries, @ResumeHandle);
if not (NetResult in [ERROR_SUCCESS, ERROR_MORE_DATA]) then
RaiseLastOSError(NetResult);
try
P := Buf;
for I := 0 to EntriesRead - 1 do
begin
if Callback(P^, Data) then
Break;
Inc(P);
end;
finally
NetApiBufferFree(Buf);
end;
until NetResult = ERROR_SUCCESS;
end;
function ShowFileInfo(const FileInfo: TFileInfo3; Data: Pointer): Boolean;
begin
Result := False;
Writeln(Format('id: %d, permissions: $%.8x, num_locks: %d, pathname: ''%s'', username: ''%s''',
[FileInfo.fi3_id, FileInfo.fi3_permissions, FileInfo.fi3_num_locks, FileInfo.fi3_pathname, FileInfo.fi3_username]));
end;
begin
try
if ParamCount = 1 then
EnumNetFileUsers(ParamStr(1), ShowFileInfo);
except
on E: Exception do
begin
Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
ExitCode := 1;
end;
end;
end.
似乎LocalPath
参数中传递的路径必须以双反斜杠开头,例如:
test.exe C:\\Dev\Test\test.exe
产生以下输出(如果文件是通过共享打开的):
id: -469761405, permissions: $00000001, num_locks: 0, pathname: 'C:\\Dev\Test\test.exe', username: 'Ondrej'
另请注意,MSDN 说:
“只有 Administrators 或 Server Operators 本地组的成员才能成功执行 NetFileEnum 函数。”