【问题标题】:Reading Command Line Arguments of Another Process (Win32 C code)读取另一个进程的命令行参数(Win32 C 代码)
【发布时间】:2023-04-08 05:24:01
【问题描述】:

我需要能够列出传递给其他正在运行的进程的命令行参数(如果有的话)。我已经有了系统上正在运行的进程的 PID,所以基本上我需要确定传递给具有给定 PID XXX 的进程的参数。

我正在研究Python module for managing processes 的核心部分。该代码以 C 语言编写为 Python 扩展,并将由更高级别的 Python 库包装。该项目的目标是避免依赖第三方库,例如 pywin32 扩展,或在命令行上调用“ps”或 taskkill 等丑陋的 hack,因此我正在寻找一种在 C 代码中执行此操作的方法。

我在谷歌上搜索了一下,发现了一些使用CreateRemoteThread() 将自己注入到另一个进程中的简短建议,然后运行GetCommandLine(),但我希望有人可能有一些工作代码示例和/或更好的建议。

更新:我在 CodeProject 上找到了完整的工作演示代码和使用 NtQueryProcessInformation 的解决方案:http://www.codeproject.com/KB/threads/GetNtProcessInfo.aspx - 这并不理想,因为它“不支持”直接从 NTDLL 结构中剔除信息,但是我会忍受它。感谢大家的建议。

更新 2:我通过更多的谷歌搜索找到了一个不使用 C++ 代码的 C 版本,并且更直接/简洁地指出了这个问题。详情请见http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/

谢谢!

【问题讨论】:

    标签: python c winapi


    【解决方案1】:

    为了回答我自己的问题,我终于找到了一个完全符合我要求的 CodeProject 解决方案:

    http://www.codeproject.com/KB/threads/GetNtProcessInfo.aspx

    正如@Reuben 已经指出的那样,您可以使用NtQueryProcessInformation 来检索此信息。不幸的是,这不是推荐的方法,但鉴于唯一的其他解决方案似乎会产生 WMI 查询的开销,我认为我们现在将采用这种方法。

    请注意,如果在 64 位 Windows 操作系统上使用从 32 位 Windows 编译的代码,这似乎不起作用,但由于我们的模块是从目标上的源代码编译的,因此对于我们的目的来说应该没问题。我宁愿使用这个现有的代码,如果它在 Windows 7 或更高版本中中断,我们可以再次查看使用 WMI。感谢您的回复!

    更新:此处展示了相同技术的更简洁且仅限 C(相对于 C++)的版本:

    http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/

    【讨论】:

      【解决方案2】:

      缓存解决方案: http://74.125.45.132/search?q=cache:-wPkE2PbsGwJ:windowsxp.mvps.org/listproc.htm+running+process+command+line&hl=es&ct=clnk&cd=1&gl=ar&client=firefox-a

      in CMD
      WMIC /OUTPUT:C:\ProcessList.txt PROCESS get Caption,Commandline,Processid
      
      or
      
      WMIC /OUTPUT:C:\ProcessList.txt path win32_process get Caption,Processid,Commandline
      

      还有: http://mail.python.org/pipermail/python-win32/2007-December/006498.html

      http://tgolden.sc.sabren.com/python/wmi_cookbook.html#running_processes 
      seems to do the trick:
      
      import wmi
      c = wmi.WMI ()
      for process in c.Win32_Process ():
        print process.CommandLine
      

      【讨论】:

      • 感谢您的建议,但是,我真的不想调用外部进程。引用的 wmi 模块还需要 pywin32 扩展之上的另一个第三方模块,我们不希望用户拥有任何一个。
      • 您可以通过其 COM 接口从 C 调用 WMI,尽管它不会是有史以来最优雅的代码。
      • @Rob - 这是真的......对于这个看似简单的任务来说,这将是一些严重的开销,但它开始看起来我没有太多选择。
      【解决方案3】:

      通过使用 psutil (https://github.com/giampaolo/psutil):

      >>> import psutil, os
      >>> psutil.Process(os.getpid()).cmdline()
      ['C:\\Python26\\python.exe', '-O']
      >>> 
      

      【讨论】:

        【解决方案4】:

        另一个回复中提到的 WMI 方法可能是最可靠的方法。浏览 MSDN,我发现了另一种可能的方法;它已记录在案,但尚不清楚它是否得到完全支持。在 MSDN 的语言中,它--

        可能会被更改或不可用 未来版本的 Windows...

        在任何情况下,只要您的进程具有正确的权限,您应该能够使用ProcessInformationClassProcessBasicInformation 调用NtQueryProcessInformation。在返回的PROCESS_BASIC_INFORMATION 结构中,您应该返回指向目标进程的process execution block 的指针(作为字段PebBaseAddress)。 PEB 的ProcessParameters 字段将为您提供指向RTL_USER_PROCESS_PARAMETERS 结构的指针。该结构的CommandLine 字段将是UNICODE_STRING 结构。 (注意不要对字符串做太多假设;不能保证它会以 NULL 结尾,并且不清楚是否需要从开头剥离已执行应用程序的名称命令行。)

        我还没有尝试过这种方法——正如我上面提到的,它似乎有点……不确定(阅读:不可移植)——但它可能值得一试。祝你好运...

        【讨论】:

        • 我看到了这个,感觉和你一样——它看起来很不稳定,但我发现的 CodeProject 演示即使在 Vista 上也能很好地工作,所以无论如何我都会使用这个。有关工作代码,请参阅 CodeProject 链接。
        【解决方案5】:

        如果您不是这些进程的父进程,那么使用记录的函数是不可能的 :( 现在,如果您是父进程,则可以执行 CreateRemoteThread 技巧,否则您几乎肯定会被拒绝访问,除非您的应用拥有管理员权限。

        【讨论】:

        • 我现在在模块中有代码,如果可能的话,它将获得 SeDebug 权限,所以如果他们是管理员用户,我们应该拥有所需的权限吗?
        猜你喜欢
        • 1970-01-01
        • 2014-11-11
        • 2011-07-06
        • 1970-01-01
        • 2013-01-27
        • 2011-09-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多