我有一个Windows服务,在特定事件中重新启动Windows,但我遇到了问题。我不想在使用Windows安装程序安装程序时重新启动Windows。
那么我如何判断Windows安装程序是否正在忙于安装或不安装。
任何Delphi或命令行功能都可以接受。
请你帮我吗?
我找到了这两个classess,但我不知道如何使用它们。
答案 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 。如果您希望了解此类型的安装程序,可以搜索正在运行的进程列表。
资源: