2011-07-11 81 views
5

我有一個應用程序位於網絡共享文件夾中的服務器上。網絡中的許多用戶可以同時使用該文件。我想執行該EXE文件的更新,爲此,我想知道誰在網絡中(除了我)正在使用該文件。如何檢查網絡共享EXE文件是否被多個用戶使用?

是否可以通過編程方式檢查?例如:列出現在正在使用該文件的所有用戶名?或至少檢索該文件上的鎖數量?

謝謝。

+0

你想從客戶機服務器側O做到這一點? – RRUZ

+1

不知道這是否正是你想要的,但SysInternal的[PsFile](http://technet.microsoft.com/en-us/sysinternals/bb897552)可以告訴你誰在某臺機器上打開了文件。他們提到使用一些我不熟悉的.NET API,但它可能會成爲你的主角。 – eran

+0

@RRUZ理想情況下,它將是一個客戶端應用程序。我不介意客戶端應用程序是否必須在服務器上運行一些updater.exe進程。 @eran謝謝,我會檢查出來。 – Wodzu

回答

7

要列出機器上打開的共享文件,您可以使用ADSI(Active Directory服務接口)。

爲了使用這些接口德爾福必須導入Active DS類型庫

enter image description here

然後訪問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. 
+0

感謝@RRUZ,不幸的是它不能按預期工作。更具體地說,它只能工作一次。如果我選擇了一些目錄與用戶共享,我啓用它並運行您的示例,它將顯示該目錄。但是,如果我關掉你的例子並再次打開它,它什麼也不顯示?很奇怪.. – Wodzu

+0

好吧,現在我明白了,即使我在我的服務器\主機上,我也需要通過網絡連接到該資源。只是出於好奇,你有沒有以前的經驗,或者你是否搜索互聯網來幫助我呢? – Wodzu

+0

當然,我在過去使用'ADSI',爲什麼要問?事實上,我已經使用了基於COM的技術,如ADSI,WMI,Scripting等。 – RRUZ

2

如果您確實需要更換可能正在使用的exe文件,您可以重命名可執行文件,然後將新文件複製到同一位置。新用戶將運行新的可執行文件,只要最後一個運行它的用戶關閉應用程序,舊的(可以重命名的)用戶就可以刪除。

+1

我已經多次成功地使用這種方法。儘管如此,我不確定它是否可靠。 –

+0

@Silver謝謝你的建議,但這對我來說是不可接受的。我還需要更新數據庫,因此我需要知道是否有人正在使用EXE。 – Wodzu

+0

@Wodzu你打算如何更新數據庫並更新單個原子事務中的EXE。直接回答你的問題,只是解決EXE更新不會使整個更新操作成爲原子。 –

0

如果您啓動exe,它將被鎖定寫入。因此,替換或重命名exe是安全的,但如果你不能這意味着使用exe。

PsFile和「網絡文件」可以顯示文件是否打開,您可以關閉文件。但這對於啓動程序的用戶來說並不好。

我認爲最好是創建函數來發送消息給程序的所有用戶。如果您需要升級禁用新登錄並向所有用戶發送消息「請退出,需要升級!」。重試此操作,直到您可以替換exe。 PsFile無法知道誰在使用文件,但只有在使用文件的情況下。

1

它可能是矯枉過正,但有一個服務器 - 客戶端架構呢?應用程序可以在您的服務器上運行,並且每次有人啓動客戶端時,都會連接到服務器。

一個「狀況/狀態」加入可以改變你的當前需要的公式:NORMAL,準備升級,正在升級,等

這種方式,您可以通過打開的連接列表循環和發送向每個人發送一條消息,說明系統將進入維護模式,或者當客戶端啓動時,它可以通知用戶發生了什麼。

乾杯

+0

我正在考慮simmilar解決方案。感謝這個想法。 – Wodzu

+0

不要提及它,越接近尋找答案的想法。 – Morfic

相關問題