如何查看Windows安装程序是否忙于使用delphi?

时间:2014-02-06 08:09:19

标签: delphi command-line windows-installer

我有一个Windows服务,在特定事件中重新启动Windows,但我遇到了问题。我不想在使用Windows安装程序安装程序时重新启动Windows。

那么我如何判断Windows安装程序是否正在忙于安装或不安装。

任何Delphi或命令行功能都可以接受。

请你帮我吗?

我找到了这两个classess,但我不知道如何使用它们。

Class1 class2

3 个答案:

答案 0 :(得分:2)

基于this article,这已经过时了,我试图实现两个建议的选项。第二个在Windows 7 SP1上为我工作。原则是查询MSIServer服务状态,并检查此服务是否正在运行并且接受SERVICE_ACCEPT_STOP控制代码。这是一个函数包装器:

uses
  WinSvc;

function IsWindowsInstallerBusy: Boolean;
var
  Service: SC_HANDLE;
  ServiceMgr: SC_HANDLE;
  ServiceStatus: SERVICE_STATUS;
begin
  Result := False;

  ServiceMgr := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
  if ServiceMgr <> 0 then
  try
    Service := OpenService(ServiceMgr, 'MSIServer', SERVICE_QUERY_STATUS);
    if Service <> 0 then
    try
      if QueryServiceStatus(Service, ServiceStatus) then
      begin
        Result := (ServiceStatus.dwCurrentState = SERVICE_RUNNING) and
          ((ServiceStatus.dwControlsAccepted and SERVICE_ACCEPT_STOP) = 0);
      end
      else
        raise Exception.CreateFmt('Cannot query service status. Code: %d',
          [GetLastError]);
    finally
      CloseServiceHandle(Service);
    end
    else
      raise Exception.CreateFmt('Cannot open service. Code: %d',
        [GetLastError]);
  finally
    CloseServiceHandle(ServiceMgr);
  end
  else
    raise Exception.CreateFmt('Cannot connect to the service control ' +
      'manager. Code: %d', [GetLastError]);
end;

答案 1 :(得分:2)

Windows Installer提供mutex来告诉您安装是否正在进行中。我会在SCManager API调用中使用它,因为它是线程安全的。 Heath Stewart(MSFT MSI专家)写了一篇关于here的文章,他的建议应该比Windows Installer团队更有信心。

答案 2 :(得分:0)

我只是在这里猜测,因为你没有提供足够的信息......

(关于目标和环境的一些细节会很好。)


1)如果您希望仅在特定安装程序未运行时重新启动Windows,则应枚举正在运行的进程,如果找到要了解的安装程序,则只需不要重新启动你的系统。

2)如果您希望获得更通用的解决方案,您仍然可以选择:.msi类型的安装程序正在使用 msiexec.exe 。如果您希望了解此类型的安装程序,可以搜索正在运行的进程列表。


资源: