Как проверить, используется ли сетевой общий EXE-файл более чем одним пользователем? - PullRequest
5 голосов
/ 11 июля 2011

У меня есть приложение, которое находится на сервере в общей сетевой папке. Многие пользователи в сети, могут использовать этот файл одновременно. Я хотел бы выполнить обновление этого EXE-файла и для этого я хотел бы знать, кто в сети (кроме меня) в настоящее время использует этот файл.

Можно ли это проверить программно? Например: перечислить все имена пользователей, которые сейчас используют этот файл? Или, по крайней мере, получить количество блокировок для этого файла?

Спасибо.

Ответы [ 4 ]

7 голосов
/ 11 июля 2011

Для просмотра списка открытых общих файлов на машине вы можете использовать ADSI (интерфейсы службы Active Directory).

Чтобы использовать эти интерфейсы из delphi, необходимо импортировать библиотеку типов 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.
2 голосов
/ 11 июля 2011

Если вам действительно нужно заменить исполняемый файл, который может использоваться, вы можете переименовать исполняемый файл, а затем просто скопировать новый файл в то же место.Новые пользователи будут запускать новый исполняемый файл, где старый (переименованный) пользователь может удалить, как только последний пользователь, запустивший его, закроет приложение.

1 голос
/ 11 июля 2011

Это может быть излишним, но как насчет архитектуры сервер-клиент? Приложение может работать на вашем сервере, и каждый раз, когда кто-то запускает клиент, оно подключается к серверу.

Добавьте «состояние / состояние» в уравнение, которое может измениться к вашим текущим потребностям: НОРМАЛЬНОЕ, ПОДГОТОВКА К ОБНОВЛЕНИЮ, ОБНОВЛЕНИЕ В ПРОГРЕССЕ и т. Д.

Таким образом, вы можете перебирать список открытых соединений и отправлять всем сообщение о том, что система будет переведена в режим обслуживания, или когда клиент запустится, он может уведомить пользователя о происходящем.

Приветствия

0 голосов
/ 11 июля 2011

Если вы запустите exe, он будет заблокирован для записи.Так что можно безопасно заменить или переименовать exe, но если вы не можете, это означает, что exe используется.

PsFile и «net file» могут показать, открыт ли файл, и вы можете закрыть файл.Но это не хорошо для пользователей, которые запускаются программой.

Я думаю, что лучше всего создать функцию отправки сообщения всем пользователям программы.Если вам нужно обновить, отключите новые логины и отправьте всем пользователям сообщение «Пожалуйста, выйдите, обновление необходимо!».Повторите это, пока вы не можете заменить exe.PsFile не может сказать, кто использует файл, но только если файл используется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...