Windows 从其可执行文件的路径获取服务名称

Windows 从其可执行文件的路径获取服务名称,windows,delphi,Windows,Delphi,我有一个可执行文件的路径,它是一个正在运行的服务应用程序 例如:C:\ProgramFiles(x86)\Someapp\somesvc.exe 我想停止并启动它,为此,我想我需要得到服务的名称,正如答案中所概述的那样 我可以通过在HKLM\System\CurrentControlSet\services中遍历所有服务的所有注册表项,并检查ImagePath注册表项是否与我的可执行路径匹配来实现这一点 这个解决办法应该行得通,但在我看来似乎不对。有更好的方法吗?您可以向WMI查询路径名类似于您

我有一个可执行文件的路径,它是一个正在运行的服务应用程序

例如:
C:\ProgramFiles(x86)\Someapp\somesvc.exe

我想停止并启动它,为此,我想我需要得到服务的名称,正如答案中所概述的那样

我可以通过在
HKLM\System\CurrentControlSet\services
中遍历所有服务的所有注册表项,并检查
ImagePath
注册表项是否与我的可执行路径匹配来实现这一点


这个解决办法应该行得通,但在我看来似乎不对。有更好的方法吗?

您可以向WMI查询路径名类似于您的路径的服务

注意:某些路径包含参数。不能使用equal(使用Like)

您可以使用以下代码查询WMI:

//-----------------------------------------------------------------------------------------------------
//     This code was generated by the Wmi Delphi Code Creator (WDCC) Version 1.9.9.350
//     http://code.google.com/p/wmi-delphi-code-creator/
//     Blog http://theroadtodelphi.wordpress.com/wmi-delphi-code-creator/
//     Author Rodrigo Ruz V. (RRUZ) Copyright (C) 2011-2015 
//----------------------------------------------------------------------------------------------------- 
//
//     LIABILITY DISCLAIMER
//     THIS GENERATED CODE IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.
//     YOU USE IT AT YOUR OWN RISK. THE AUTHOR NOT WILL BE LIABLE FOR DATA LOSS,
//     DAMAGES AND LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS CODE.
//
//----------------------------------------------------------------------------------------------------
program GetWMI_Info;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;



// La clase Win32_Service representa un servicio en un sistema Win32. Un 
// aplicación de servicio cumple las reglas de la interfaz del Administrador de 
// control de servicios (SCM, Service Control Manager) y un usuario la puede 
// iniciar automáticamente al arrancar el sistema a través del programa Servicios 
// del Panel de control o mediante una aplicación que utilice las funciones de 
// servicio de la API de Win32. Los servicios se pueden ejecutar aunque ningún 
// usuario haya iniciado sesión en el sistema.

procedure  GetWin32_ServiceInfo(sPath:String);
const
  WbemUser            ='';
  WbemPassword        ='';
  WbemComputer        ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_Service WHERE PathName like "%' + sPath + '%"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    Writeln(Format('Caption        %s',[String(FWbemObject.Caption)]));// String
    Writeln(Format('DisplayName    %s',[String(FWbemObject.DisplayName)]));// String
    Writeln(Format('Name           %s',[String(FWbemObject.Name)]));// String
    Writeln(Format('PathName       %s',[String(FWbemObject.PathName)]));// String

    Writeln('');
    FWbemObject:=Unassigned;
  end;
end;


begin
 try
    CoInitialize(nil);
    try
      GetWin32_ServiceInfo(ExtractFileName('c:\windows\system\locator.exe'));
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode])); 
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;      
end.
如果需要更多属性,请添加到程序

对于使用:
'c:\windows\system\locator.exe'
进行查询,您可以获得:

对于使用“
”C:\Program Files(x86)\Skype\Updater\Updater.exe”
进行查询,您可以获得:


对于启动停止服务,您需要
属性名称

使用或枚举已安装的服务。这将为您提供每个服务的名称,但不是其
ImagePath
。要检索它,您可以使用打开每个服务,然后使用获取其
ImagePath

为什么不使用服务控制管理器API?@DavidHeffernan正如我在问题中所链接的,我将使用它,但它期望作为服务名称作为输入,而不是服务路径,这是这里的主要问题。服务控制经理知道所有服务及其所有细节。用它来提取你需要的信息。我只是建议您使用官方API,而不是入侵注册表。当然,可以很容易地使用相同的名称注册多个服务,甚至不是所有的服务都有它们的可执行文件。从Vista开始,它被认为是系统资源的紧张,并努力将这些可执行文件转换为共享服务。这是一个备份步骤:你是如何在不知道服务名称的情况下重新启动服务的?也许你可以解决这个问题,让剩下的问题变得更容易。我对此投了反对票,因为WMI在我看来是“邪恶的”,它速度慢,而且有很多开销。SCM API可用于迭代服务和比较路径@雷姆科。这是个人意见。对于一个问题,可能有几种有效的解决方案。对你来说是坏的,对另一个人来说是好的。我不理解投反对票,因为解决方案不是你提出的或你喜欢的。这是一个非常糟糕的解决方案。WMI是作业的错误工具。我的否决票也是。因为WMI是一个真正用于编写脚本的解决方案,速度非常慢,因此会给应用程序增加不必要的延迟。如果WMI是唯一的方法,那很好,但是有一个很好的api,从早期开始就在Windows中,并且在Delphi中很容易访问。即使这是一个理想的解决方案,这段代码也没有错误检查。如果WMI没有运行(我以前见过),该怎么办?如果用户没有足够的权限怎么办?如果请求的服务不存在怎么办?更进一步-如果同一个可执行文件生成了多个服务怎么办?是的,这是可能的。这是正确的解决方案,谢谢。尽管我需要深入研究,但大多数关于这些函数的在线教程在新的delphi版本中无法正常工作。