【问题标题】:How do I get the command-line arguments of a Windows service?如何获取 Windows 服务的命令行参数?
【发布时间】:2011-09-05 04:24:53
【问题描述】:

我正在寻找一种方法来找出 any Windows 服务的命令行参数。

对于非服务进程,可以在 Windows 任务管理器中找到命令行参数,或者使用 WMI 以编程方式找到,如 this post 所示。

很遗憾,这两种解决方案不适用于由ServiceController.Start(String[] args) 方法启动的 Windows 服务。即使传入了一些参数,它们都只在命令行上显示可执行文件路径。

  1. 有什么区别 在两个场景之间(服务与 非服务进程)?
  2. 有没有 找出论点的方法 Windows 服务?

我还尝试创建一个简单的服务,该服务只将它具有的任何命令行参数记录到事件日志中。我使用"sc.exe start <my service> <arg1>" 启动它并验证<arg1> 已写入事件日志。

但是,没有一个解决方案对我有用。我仍然只看到可执行文件的路径。我的操作系统版本是 Windows Server 2008 R2 SP1 x64 Enterprise。

【问题讨论】:

    标签: c# .net windows service


    【解决方案1】:

    服务有两种类型的参数:

    • 在进程启动命令行上传递的参数。您可以使用 Process Explorer 等轻松找到那些。
    • 传递给ServiceMain function 的参数。这是服务应该实现的 WINdows API。 .NET 等效项是 ServiceBase.OnStart。这是您执行SC START \[arguments\] 时使用的内容。这与“命令行进程参数”无关。

    第二种类型的参数可能只有服务本身知道,如果实现使用它,许多服务不是这样。当我们查看像 PEB 这样的低级 Windows 结构时,我认为 Windows 不会跟踪这一点:Process and Thread Structures (MSDN),即使是其中未记录的部分,Undocumented functions of NTDLL

    【讨论】:

    • 感谢您的回答,西蒙。你也许是对的。我无法从内部邮件列表中得到更好的答案。可能有一些 hacky 方法可以解决这个问题,但我检查了 SCM API,但似乎没有帮助。
    • 这是正确的。请注意,一个服务进程可以包含多个服务(SvcHost.exe 就是一个众所周知的示例)。在这些情况下,有多个ServiceMain 调用,这表明您需要的不仅仅是主机进程来查找特定ServiceMain 的参数。同理,你在单个 PEB 中找不到答案。
    【解决方案2】:

    您可以找到服务 EXE 文件的详细信息并进行编辑,或者只查看服务注册表项中的命令行选项。你会在下面找到

    HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services
    

    如果您决定更改此设置,请务必重新启动 服务 窗口,因为它不会实时重新读取。

    【讨论】:

    • 感谢您的提示,但即使此注册表也不显示 Windows 服务的命令行参数。最接近的键是“ImagePath”,它显示了服务可执行文件的路径,如任务管理器、Procexp.exe 和我编写的程序。
    • 我至少在一些服务上看到过,在 ImagePath 的末尾有命令行参数。例如:ImagePath="c:\mongo\mongod.exe --dbperdirectory --dbpath=c:\data\mongo"
    • 谢谢,正是我需要的!
    • “ControlSet001”是否与“CurrentControlSet”相同?在任何情况下,这都是我正在寻找的答案(至少不仅仅是阅读,而是编辑它)+1 也是因为这个答案不假设用户拥有源代码(或反射方法,因为服务可能已经在没有 .NET 的情况下用 C++ 编写)最后但并非最不重要的一点是,因为它是注册表,MSI/WiX 可以在没有外部应用程序(例如“ProcExplorer”)的情况下访问它;谢谢!!!
    【解决方案3】:

    Sysinternals尝试Process Explorer应用程序

    它就像任务管理器,只是它列出了所有正在运行的进程。选择您的服务并查看其属性。

    【讨论】:

    • 我之前实际上尝试过 procexp.exe,它也显示了与任务管理器显示的相同的内容。我也应该提到尝试一下。顺便谢谢。
    • 我已经检查了一些服务进程资源管理器正在显示命令行参数
    • 哪些服务?我编辑了我的问题以添加更多信息。我基本上尝试了一个简单的服务,我使用“SC.exe start ”启动并传递了一个参数,所有建议的解决方案都不适合我。
    • 我检查了 SQLServer 服务。我用的是win7 X64
    【解决方案4】:
    1. 服务进程没有像通常的 EXE 文件一样启动。甚至,服务进程可能只是一个 .dll 文件。请参阅:Windows service(维基百科)。

      许多出现在 Windows 任务管理器的进程列表中,通常使用用户名 SYSTEM、LOCAL SERVICE 或 NETWORK SERVICE,但并非所有具有 SYSTEM 用户名的进程都是服务。其余的服务通过 svchost.exe 作为 DLL 加载到内存中运行。

    2. 只需覆盖ServiceBase.OnStart(string[] args) 方法。查看更多: ServiceBase.OnStart(String[]) Method (MSDN)

    【讨论】:

    • 谢谢,但我的意思是要询问有关计算任何 Windows 服务的命令行参数的问题,而不是我创建的那个,所以我不能像你在 #2 中所说的那样覆盖该方法。我也在寻找两种情况之间的区别,为什么对于交互过程我可以看到参数,但对于服务我看不到。
    【解决方案5】:

    使用Powershell可以调用

    (Get-CimInstance Win32_Service -Filter 'Name = "<my service>"').PathName
    

    获取服务的完整命令行(返回文件和参数)

    只需将 替换为所需服务的名称即可。

    例如:

    (Get-CimInstance Win32_Service -Filter 'Name = "Dnscache"').PathName
    

    返回“C:\WINDOWS\system32\svchost.exe -k NetworkService -p

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-22
      • 2015-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      • 1970-01-01
      相关资源
      最近更新 更多