我需要能够列出传递给其他正在运行的进程的命令行参数(如果有的话)。我已经在系统上运行进程的PID了,所以基本上我需要确定传递给给定PID XXX 的进程的参数。
我正在研究Python module for managing processes的核心部分。代码在C中编写为Python扩展,并将由更高级别的Python库包装。这个项目的目标是避免依赖于第三方库,例如pywin32扩展,或者在命令行上调用'ps'或taskkill等丑陋的黑客,所以我正在寻找一种在C代码中执行此操作的方法。
我已经用Google搜索了一些,并找到了一些简短的建议,即使用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/。
谢谢!
答案 0 :(得分:6)
为了回答我自己的问题,我终于找到了一个完全符合我要求的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/
答案 1 :(得分:5)
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
答案 2 :(得分:3)
使用psutil(https://github.com/giampaolo/psutil):
>>> import psutil, os
>>> psutil.Process(os.getpid()).cmdline()
['C:\\Python26\\python.exe', '-O']
>>>
答案 3 :(得分:2)
另一个响应中提到的WMI方法可能是执行此操作的最可靠方式。通过MSDN,我发现了另一种可能的方法;它已被记录,但尚不清楚它是否得到完全支持。在MSDN的语言中,它 -
可能会被更改或不可用 未来版本的Windows ...
在任何情况下,只要您的流程具有正确的权限,您就应该能够使用ProcessInformationClass
ProcessBasicInformation
来呼叫NtQueryProcessInformation
。在返回的PROCESS_BASIC_INFORMATION
结构中,您应该返回指向目标进程process execution block的指针(作为字段PebBaseAddress
)。 PEB的ProcessParameters
字段将为您提供指向RTL_USER_PROCESS_PARAMETERS
结构的指针。该结构的CommandLine
字段将是UNICODE_STRING
结构。 (注意不要对字符串做太多假设;不能保证它会以NULL结尾,并且不清楚你是否需要从开始时删除已执行应用程序的名称命令行。)
我没有尝试过这种方法 - 正如我上面提到的,它似乎有点...... iffy(读取:非便携式) - 但它可能值得一试。祝你好运......
答案 4 :(得分:0)
如果您不是这些进程的父级,那么使用记录的函数就不可能:(现在,如果您是父级,则可以执行CreateRemoteThread技巧,但除此之外您几乎肯定会获得拒绝访问权限,除非您的应用拥有管理员权限。