问题
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.
回答1:
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
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.
回答2:
If what you really need is to replace an exe file, that may be in use, you can rename the executable, and then just copy the new file on the same location. New users will run the new executable, where as the old (renamed) one can be deleted as soon as the last user, running it, closes the application.
回答3:
It might be overkill, but what about having a server-client architecture? An app could be running on your server, and each time someone launches a client, it connects to the server.
Add a "status/state" to the equation which can change to your current need: NORMAL, PREPARING FOR UPGRADE, UPGRADE IN PROGRESS, etc
This way you could iterate through the list of opened connections and send a message to everyone that the system will be put in maintenance mode, or when the client gets launched it can notify the user of what's going on.
Cheers
回答4:
If you start exe it will be locked for write. So it is safe to replace or rename exe, but if you can not this mean that exe is used.
PsFile and "net file" can show if file is opened and you can close file. But this is not good for users that are started program.
I think it is best if you create function to send message to all users of program. If you need upgrade disable new logins and send message to all users "Please exit, upgrade is required!". Retry this until you can replace exe. PsFile can not tell who is using file but only if file is used.
来源:https://stackoverflow.com/questions/6649567/how-to-check-if-network-shared-exe-file-is-used-by-more-than-one-user