我有一個應用程序位於網絡共享文件夾中的服務器上。網絡中的許多用戶可以同時使用該文件。我想執行該EXE文件的更新,爲此,我想知道誰在網絡中(除了我)正在使用該文件。如何檢查網絡共享EXE文件是否被多個用戶使用?
是否可以通過編程方式檢查?例如:列出現在正在使用該文件的所有用戶名?或至少檢索該文件上的鎖數量?
謝謝。
我有一個應用程序位於網絡共享文件夾中的服務器上。網絡中的許多用戶可以同時使用該文件。我想執行該EXE文件的更新,爲此,我想知道誰在網絡中(除了我)正在使用該文件。如何檢查網絡共享EXE文件是否被多個用戶使用?
是否可以通過編程方式檢查?例如:列出現在正在使用該文件的所有用戶名?或至少檢索該文件上的鎖數量?
謝謝。
要列出機器上打開的共享文件,您可以使用ADSI(Active Directory服務接口)。
爲了使用這些接口德爾福必須導入Active DS類型庫
然後訪問IADsFileServiceOperations
接口,其中包含一個名爲Resources
這個方法方法返回一個集合的所有共享資源開放。
入住此示例代碼
{$APPTYPE CONSOLE}
uses
ActiveDs_TLB,
Variants,
ActiveX,
SysUtils;
function ADsGetObject(lpszPathName:WideString; const riid:TGUID; out ppObject):HRESULT; safecall; external 'activeds.dll';
procedure ListSharedResourcesInUse;
var
FSO : IADsFileServiceOperations;
Resources : IADsCollection;
Resource : OleVariant;
pceltFetched : Cardinal;
oEnum : IEnumvariant;
begin
//establish the connection to ADSI
ADsGetObject('WinNT://./lanmanserver', IADsFileServiceOperations, FSO);
//get the resources interface
Resources := FSO.Resources;
//get the enumerator
oEnum:= IUnknown(Resources._NewEnum) as IEnumVariant;
while oEnum.Next(1, Resource, pceltFetched) = 0 do
begin
Writeln(Format('Resource %s User %s',[Resource.Path,Resource.User]));
Resource:=Unassigned;
end;
end;
begin
try
CoInitialize(nil);
try
ListSharedResourcesInUse;
finally
CoUninitialize;
end;
except
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Writeln('Press Enter to exit');
Readln;
end.
如果您確實需要更換可能正在使用的exe文件,您可以重命名可執行文件,然後將新文件複製到同一位置。新用戶將運行新的可執行文件,只要最後一個運行它的用戶關閉應用程序,舊的(可以重命名的)用戶就可以刪除。
我已經多次成功地使用這種方法。儘管如此,我不確定它是否可靠。 –
@Silver謝謝你的建議,但這對我來說是不可接受的。我還需要更新數據庫,因此我需要知道是否有人正在使用EXE。 – Wodzu
@Wodzu你打算如何更新數據庫並更新單個原子事務中的EXE。直接回答你的問題,只是解決EXE更新不會使整個更新操作成爲原子。 –
如果您啓動exe,它將被鎖定寫入。因此,替換或重命名exe是安全的,但如果你不能這意味着使用exe。
PsFile和「網絡文件」可以顯示文件是否打開,您可以關閉文件。但這對於啓動程序的用戶來說並不好。
我認爲最好是創建函數來發送消息給程序的所有用戶。如果您需要升級禁用新登錄並向所有用戶發送消息「請退出,需要升級!」。重試此操作,直到您可以替換exe。 PsFile無法知道誰在使用文件,但只有在使用文件的情況下。
你想從客戶機服務器側O做到這一點? – RRUZ
不知道這是否正是你想要的,但SysInternal的[PsFile](http://technet.microsoft.com/en-us/sysinternals/bb897552)可以告訴你誰在某臺機器上打開了文件。他們提到使用一些我不熟悉的.NET API,但它可能會成爲你的主角。 – eran
@RRUZ理想情況下,它將是一個客戶端應用程序。我不介意客戶端應用程序是否必須在服務器上運行一些updater.exe進程。 @eran謝謝,我會檢查出來。 – Wodzu