我有一个应用程序,它位于网络共享文件夹中的服务器上。网络中的许多用户,可以同时使用该文件。我想执行该 EXE 文件的更新并执行此操作,我想知道网络中的谁(除了我)当前正在使用该文件。
是否可以通过编程方式进行检查?例如:列出现在正在使用该文件的所有用户名?或者至少检索该文件上的锁数?
谢谢。
我有一个应用程序,它位于网络共享文件夹中的服务器上。网络中的许多用户,可以同时使用该文件。我想执行该 EXE 文件的更新并执行此操作,我想知道网络中的谁(除了我)当前正在使用该文件。
是否可以通过编程方式进行检查?例如:列出现在正在使用该文件的所有用户名?或者至少检索该文件上的锁数?
谢谢。
要列出机器中打开的共享文件,您可以使用 ADSI(Active Directory 服务接口)。
为了从 delphi 使用这些接口,您必须导入 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 文件,您可以重命名可执行文件,然后将新文件复制到同一位置。新用户将运行新的可执行文件,而旧的(重命名的)可执行文件可以在最后一个运行它的用户关闭应用程序时被删除。
这可能有点矫枉过正,但是拥有一个服务器-客户端架构呢?应用程序可能正在您的服务器上运行,每次有人启动客户端时,它都会连接到服务器。
将“状态/状态”添加到可以更改为您当前需求的等式中:正常、准备升级、升级中等
这样,您可以遍历打开的连接列表并向每个人发送一条消息,系统将进入维护模式,或者当客户端启动时,它可以通知用户正在发生的事情。
干杯
如果您启动 exe,它将被锁定以进行写入。所以替换或重命名exe是安全的,但如果你不能,这意味着使用了exe。
PsFile 和“net file”可以显示文件是否打开,您可以关闭文件。但这对启动程序的用户不利。
我认为最好创建功能以向程序的所有用户发送消息。如果您需要升级禁用新登录并向所有用户发送消息“请退出,需要升级!”。重试此操作,直到您可以替换 exe。PsFile 无法判断谁在使用文件,但只能判断是否使用了文件。