Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何确定Windows installer是否正在使用delphi?_Delphi_Command Line_Windows Installer - Fatal编程技术网

如何确定Windows installer是否正在使用delphi?

如何确定Windows installer是否正在使用delphi?,delphi,command-line,windows-installer,Delphi,Command Line,Windows Installer,我有一个在特定事件中重新启动Windows的Windows服务,但我有一个问题。当windows使用windows installer安装程序时,我不想重新启动windows 因此,我如何判断Windows installer是否正在忙着安装某些东西 任何Delphi或命令行函数都是可以接受的 你能帮帮我吗 我找到了这两个类,但我不知道如何使用它们 基于,这已经过时了,我已经尝试实现了两个建议的选项。第二个在Windows7SP1上对我有效。其原理是查询MSIServer服务状态,并检查该服务是

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

因此,我如何判断Windows installer是否正在忙着安装某些东西

任何Delphi或命令行函数都是可以接受的

你能帮帮我吗

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

基于,这已经过时了,我已经尝试实现了两个建议的选项。第二个在Windows7SP1上对我有效。其原理是查询MSIServer服务状态,并检查该服务是否正在运行以及是否接受控制代码。下面是一个函数包装器:

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;
基于,这是非常过时的,我已经尝试实现这两个建议的选项。第二个在Windows7SP1上对我有效。其原理是查询MSIServer服务状态,并检查该服务是否正在运行以及是否接受控制代码。下面是一个函数包装器:

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如果您希望仅在特定安装程序未运行时重新启动windows,则应枚举正在运行的进程,如果您找到要了解的安装程序,则不要重新启动系统

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

资源:

关于进程枚举阅读 关于从delphi做这件事 我只是在这里猜测,因为你没有提供足够的信息

关于目标和情况的一些细节会很好

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

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

资源:

关于进程枚举阅读 关于从delphi做这件事

Windows Installer提供了一个通知,告诉您是否正在进行安装。我会在SCManager API调用上使用它,因为它是线程安全的。MSI专家希思·斯图尔特(Heath Stewart MSFT)写了这篇文章,他的建议应该比Windows Installer团队的建议更可信

Windows Installer提供了一个通知,告诉您是否正在进行安装。我会在SCManager API调用上使用它,因为它是线程安全的。MSI专家希思·斯图尔特(Heath Stewart MSFT)写了这篇文章,他的建议应该比Windows Installer团队的建议更可信

枚举的问题是:当MSI软件包在未运行中未开始安装msiexec.exe,但安装完成时,msiexec.exe仍在运行,因此枚举对此没有帮助。这取决于您对它的定义[windows]正在使用windows installer安装程序。我认为虽然msiexec.exe没有启动,但安装没有启动。无论如何,TLama的答案比我的答案更正确。枚举的问题是:当MSI软件包没有开始安装msiexec.exe时,安装没有运行,但安装完成后,msiexec.exe仍在运行,因此枚举对这一点没有帮助。这取决于您对它的定义[windows]正在使用windows installer安装程序。我认为虽然msiexec.exe没有启动,但安装没有启动。无论如何,特拉玛的答案比我的更正确。尽管这篇文章已经过时,但它仍然是我认为最可靠的来源。它是由Windows Installer团队编写的。在这篇文章的评论中,希思·斯图尔特(Heath Stewart)说要继续使用互斥锁。希思知道他的事。@Christopher,啊,谢谢你的否决票!试着检查一下“MSI执行互斥”是否是你自己创建的……它不是个人的,你受到了MSI团队错误信息的攻击。@Zeid,你能接受这里的另一个答案吗?尽管这篇文章已经过时,但它仍然是我所说的最可靠的来源。它是由Windows Installer团队编写的。在这篇文章的评论中,希思·斯图尔特(Heath Stewart)说要继续使用互斥锁。希思知道他的事。@Christopher,啊,谢谢你的否决票!试着检查一下“MSI执行互斥”是否是你自己创建的……它不是个人的,你是MSI团队错误信息的牺牲品。@Zeid,你能接受这里的另一个答案吗?嗯,你尝试过这种技术吗?我能看到的唯一一个由
msiexec.exe进程是进程资源管理器中的\Sessions\1\BaseNamedObjects\MSCTF.Asm.MutexDefault1。所以,即使它可能更可信,它仍然是一篇有8年历史的文章,从那时起,许多人可能已经改变了。MSI的文档是灾难性的。[Windows 7 SP1]我从事安装程序工作17年,从事Windows安装程序工作11年。不管是好是坏,MSI多年来没有改变。他们在这里和那里添加了一些东西,但是他们非常注重向后兼容性,而且更改速度很慢。互斥锁是有效的,当MSI在其执行序列中时创建互斥锁。UI序列不会创建互斥,因为客户端不进行安装。那么,您尝试过这种技术吗?我能看到的唯一由msiexec.exe进程创建的互斥体是进程资源管理器中的\Sessions\1\BaseNamedObjects\MSCTF.Asm.MutexDefault1。所以,即使它可能更可信,它仍然是一篇有8年历史的文章,从那时起,许多人可能已经改变了。MSI的文档是灾难性的。[Windows 7 SP1]我从事安装程序工作17年,从事Windows安装程序工作11年。不管是好是坏,MSI多年来没有改变。他们在这里和那里添加了一些东西,但是他们非常注重向后兼容性,而且更改速度很慢。互斥锁是有效的,当MSI在其执行序列中时创建互斥锁。UI序列不会创建互斥,因为客户端不进行安装。