Search code examples
windowsdelphifilenetwork-share

How to check if network shared EXE file is used by more than one user?


I have an application which sits on a server in the network shared folder. Many users in network, can use that file simultaneously. I would like to perform an update of that EXE file and to do this, I would like to know who in network (besides me) is currently using that file.

Is it possible to check this programmatically? For example: to list all user names who are using that file now? Or atleast to retrieve number of locks on that file?

Thanks.


Solution

  • To list the open shared files in a machine you can use ADSI (Active Directory Service Interfaces).

    In order to use these interfaces from delphi you must import the Active DS type library

    enter image description here

    Then access the IADsFileServiceOperations interface, which contains a method called Resources this method return a collection with all the shared resources opened.

    Check this sample code

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