2011-07-11 16 views
5

Tôi có một ứng dụng nằm trên một máy chủ trong thư mục chia sẻ mạng. Nhiều người dùng trong mạng, có thể sử dụng tệp đó cùng một lúc. Tôi muốn thực hiện một cập nhật của tập tin EXE và để làm điều này, tôi muốn biết ai trong mạng (bên cạnh tôi) hiện đang sử dụng tập tin đó.Làm thế nào để kiểm tra xem mạng chia sẻ tệp EXE có được sử dụng bởi nhiều người dùng không?

Có thể kiểm tra chương trình này không? Ví dụ: để liệt kê tất cả tên người dùng đang sử dụng tệp đó ngay bây giờ? Hoặc ít nhất để lấy số lượng khóa trên tập tin đó?

Cảm ơn.

+0

Bạn có muốn làm điều này từ phía máy chủ o từ một máy khách hàng? – RRUZ

+1

Không chắc chắn nếu điều này là chính xác những gì bạn đang tìm kiếm, nhưng [PsFile] của SysInternal (http://technet.microsoft.com/en-us/sysinternals/bb897552) có thể cho bạn biết ai đã mở các tệp trên một máy nhất định. Họ đề cập đến sử dụng một số NET API, mà tôi không quen thuộc với, nhưng nó có thể là một dẫn cho bạn. – eran

+0

@RRUZ Lý tưởng nhất là ứng dụng khách. Tôi không nhớ nếu ứng dụng khách hàng phải chạy một số quá trình updater.exe trên máy chủ. @anan cảm ơn, tôi sẽ kiểm tra. – Wodzu

Trả lời

7

Để liệt kê các tệp được chia sẻ mở trong máy, bạn có thể sử dụng ADSI (Giao diện dịch vụ Active Directory).

Để sử dụng các giao diện từ delphi bạn phải nhập Active DS loại thư viện

enter image description here

Sau đó truy cập vào giao diện IADsFileServiceOperations, trong đó có một phương pháp gọi là Resources phương pháp này trả về một bộ sưu tập với tất cả các chia sẻ mở tài nguyên.

Kiểm tra này mẫu mã

{$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

Cảm ơn @RRUZ, tiếc là nó không hoạt động như mong đợi. Để cụ thể hơn, nó chỉ hoạt động một lần. Nếu tôi chọn một số thư mục để chia sẻ với người dùng, tôi bật nó và chạy ví dụ của bạn nó cho thấy thư mục đó. Nhưng sau đó nếu tôi tắt ví dụ của bạn và bật nó một lần nữa, nó cho thấy không có gì? Rất lạ .. – Wodzu

+0

Ok, bây giờ tôi nhận được nó, tôi cần phải kết nối với tài nguyên đó thông qua mạng ngay cả khi tôi đang ở máy chủ của tôi \ máy chủ. Chỉ cần ra khỏi sự tò mò, có bạn hade kinh nghiệm trước đó với điều này hoặc bạn đã tìm kiếm trên Internet để giúp tôi với điều này? – Wodzu

+0

Chắc chắn tôi đã làm việc với 'ADSI' trong quá khứ, tại sao bạn hỏi ?. Trong thực tế, tôi đã làm việc rất nhiều với các công nghệ dựa trên COM Giống như ADSI, WMI, Scripting và các công nghệ khác. – RRUZ

2

Nếu những gì bạn thực sự cần là thay thế tệp exe, có thể đang được sử dụng, bạn có thể đổi tên tệp thực thi và sau đó chỉ sao chép tệp mới trên cùng một vị trí. Người dùng mới sẽ chạy tệp thực thi mới, nơi có thể xóa tệp cũ (được đổi tên) ngay khi người dùng cuối cùng chạy nó, đóng ứng dụng.

+1

Tôi đã sử dụng phương pháp này thành công trong nhiều trường hợp. Tuy nhiên, tôi không chắc nó có đáng tin cậy hay không. –

+0

@Silver cảm ơn đề xuất, nhưng điều này là không thể chấp nhận được đối với tôi. Tôi cần phải cập nhật cơ sở dữ liệu, vì vậy tôi cần biết là ai đó hiện đang sử dụng EXE hay không. – Wodzu

+0

@Wodzu Làm thế nào bạn sẽ cập nhật cơ sở dữ liệu và cập nhật EXE trong một giao dịch nguyên tử duy nhất. Một câu trả lời trực tiếp cho câu hỏi của bạn, chỉ cần giải quyết cập nhật EXE sẽ không làm cho toàn bộ hoạt động cập nhật nguyên tử. –

0

Nếu bạn bắt đầu thoát, nó sẽ bị khóa để ghi. Vì vậy, nó là an toàn để thay thế hoặc đổi tên exe, nhưng nếu bạn không thể điều này có nghĩa là exe được sử dụng.

PsFile và "tệp net" có thể hiển thị nếu tệp được mở và bạn có thể đóng tệp. Nhưng điều này không tốt cho người dùng bắt đầu chương trình.

Tôi nghĩ tốt nhất là bạn nên tạo chức năng gửi tin nhắn cho tất cả người dùng chương trình. Nếu bạn cần nâng cấp vô hiệu hóa đăng nhập mới và gửi tin nhắn cho tất cả người dùng "Hãy thoát, nâng cấp được yêu cầu!". Thử lại cho đến khi bạn có thể thay thế exe. PsFile không thể cho biết ai đang sử dụng tệp nhưng chỉ khi tệp được sử dụng.

1

Nó có thể là quá mức cần thiết, nhưng về kiến ​​trúc máy chủ-khách hàng thì sao? Một ứng dụng có thể chạy trên máy chủ của bạn và mỗi lần ai đó khởi chạy ứng dụng khách, ứng dụng sẽ kết nối với máy chủ.

Thêm một "tình trạng/trạng thái" để phương trình có thể thay đổi nhu cầu hiện tại của bạn: NORMAL, CHUẨN BỊ CHO UPGRADE, NÂNG CẤP TRÊN TIẾN, vv

Bằng cách này bạn có thể lặp qua danh sách các kết nối mở và gửi thông báo cho mọi người rằng hệ thống sẽ được đưa vào chế độ bảo trì hoặc khi khách hàng được khởi chạy, hệ thống có thể thông báo cho người dùng về những gì đang xảy ra.

Chúc mừng

+0

Tôi đã suy nghĩ về giải pháp simmilar. Cảm ơn ý tưởng. – Wodzu

+0

Đừng đề cập đến nó, càng có nhiều ý tưởng gần hơn để tìm câu trả lời. – Morfic

Các vấn đề liên quan