指定的服务在delphi应用程序上标记为删除
我编写了一个Delphi应用程序(基本上是一个用于管理服务的GUI,它具有以下功能:允许用户设置服务使用的一些参数以及启动/停止/取消挂起/安装新版本).
因此,在所有功能中,有一个“行为不正常”:在某个时刻,应用程序尝试卸载并安装新版本的服务. 使用ShellExecute,我运行以下命令: C:myPathmyService.exe /Uninstall C:myPathmyService.exe /Install // this is tipically done to install a newer version of it 如果服务已经运行,它将成功卸载(我得到“成功卸载”消息),但是如果我打开services.msc,我看到myService仍然在服务列表中,但是从其弹出菜单中禁用了“启动”和“停止”(同时我想它根本没有列出. 此时如果我尝试安装该服务,我会收到以下错误: 请注意,如果我从命令提示符运行卸载和安装命令,卸载就可以了,服务不在services.msc列表中.注意:在这种情况下,我的意思是根本不使用Delphi(或编译的exe). 我尝试了许多技巧,包括卸载后放入睡眠(10000),但它不起作用我也尝试通过保持services.msc关闭(因为我读到它可能是一个问题,让它打开). 我使用以下步骤找到了一个成功的技巧: 1)我在从Delphi调用Uninstall之后放了一个断点 2)我去了services.msc:服务仍然在列表中,即使在“刷新”之后它仍然是列表中的stil 3)我打破(从IDE:CTRL F2)应用程序的优先级 4)我再次在services.msc中单击“刷新”按钮:myservice从列表中删除,因为它应该是 所以我怀疑Delphi XE2(无论是在IDE中调试还是运行exe)都以某种方式“锁定服务”而不允许它完全卸载. 注意:该服务是使用另一个delphi项目构建的! 你能帮我理解为什么ShellExecute进行的服务卸载确实会出现这个错误吗? 非常感谢. 重要: 解决方法
我有类似的经历.在我的代码中,我发现我使用了一个变量来保持与服务控制管理器的开放连接.如今,我将所有句柄声明为本地变量和服务即时安装和卸载.
您可以通过调用DeleteService来卸载服务.在备注部分中,它显示为:
因此,它必须停止,你应该关闭所有句柄.下面的代码应该可以解决问题: function UninstallService(aServiceName: String; aTimeOut: Cardinal): Boolean; var ComputerName: array[0..MAX_COMPUTERNAME_LENGTH + 1] of Char; ComputerNameLength,StartTickCount: Cardinal; SCM: SC_HANDLE; ServiceHandle: SC_HANDLE; ServiceStatus: TServiceStatus; begin Result:= False; ComputerNameLength:= MAX_COMPUTERNAME_LENGTH + 1; if (Windows.GetComputerName(ComputerName,ComputerNameLength)) then begin SCM:= OpenSCManager(ComputerName,nil,SC_MANAGER_ALL_ACCESS); if (SCM <> 0) then begin try ServiceHandle:= OpenService(SCM,PChar(aServiceName),SERVICE_ALL_ACCESS); if (ServiceHandle <> 0) then begin // make sure service is stopped QueryServiceStatus(ServiceHandle,ServiceStatus); if (not (ServiceStatus.dwCurrentState in [0,SERVICE_STOPPED])) then begin // Stop service ControlService(ServiceHandle,SERVICE_CONTROL_STOP,ServiceStatus); end; // wait for service to be stopped StartTickCount:= GetTickCount; QueryServiceStatus(ServiceHandle,ServiceStatus); if (ServiceStatus.dwCurrentState <> SERVICE_STOPPED) then begin repeat Sleep(1000); QueryServiceStatus(ServiceHandle,ServiceStatus); until (ServiceStatus.dwCurrentState = SERVICE_STOPPED) or ((GetTickCount - StartTickCount) > aTimeout); end; Result:= DeleteService(ServiceHandle); CloseServiceHandle(ServiceHandle); end; finally CloseServiceHandle(SCM); end; end; end; end; 我会在几个子函数(即QueryServiceStatus,StopService和UninstallService)中删除上面的代码,但是为了测试这段代码是否适合你,我认为最好用一个简单的解决方案来编写它.最后,请注意,进程需要足够的权限才能成功执行此代码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |