python 读取另一个进程的命令行参数(Win32 C 代码)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/440932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading Command Line Arguments of Another Process (Win32 C code)
提问by Jay
I need to be able to list the command line arguments (if any) passed to other running processes. I have the PIDs already of the running processes on the system, so basically I need to determine the arguments passed to process with given PID XXX.
我需要能够列出传递给其他正在运行的进程的命令行参数(如果有)。我已经有了系统上正在运行的进程的 PID,所以基本上我需要确定传递给进程的参数给定的 PID XXX。
I'm working on a core piece of a Python module for managing processes. The code is written as a Python extension in C and will be wrapped by a higher level Python library. The goal of this project is to avoid dependency on third party libs such as the pywin32 extensions, or on ugly hacks like calling 'ps' or taskkill on the command line, so I'm looking for a way to do this in C code.
我正在研究用于管理进程的Python 模块的核心部分。该代码是用 C 语言编写的 Python 扩展,并将由更高级别的 Python 库包装。这个项目的目标是避免依赖第三方库,比如 pywin32 扩展,或者像在命令行上调用 'ps' 或 taskkill 这样的丑陋的 hack,所以我正在寻找一种在 C 代码中做到这一点的方法。
I've Googled this around and found some brief suggestions of using CreateRemoteThread()to inject myself into the other process, then run GetCommandLine()but I was hoping someone might have some working code samples and/or better suggestions.
我在谷歌上搜索了一些关于使用CreateRemoteThread()将自己注入另一个进程的简短建议,然后运行GetCommandLine()但我希望有人可能有一些工作代码示例和/或更好的建议。
UPDATE: I've found full working demo code and a solution using NtQueryProcessInformation on CodeProject: http://www.codeproject.com/KB/threads/GetNtProcessInfo.aspx- It's not ideal since it's "unsupported" to cull the information directly from the NTDLL structures but I'll live with it. Thanks to all for the suggestions.
更新:我在 CodeProject 上找到了完整的工作演示代码和使用 NtQueryProcessInformation 的解决方案:http: //www.codeproject.com/KB/threads/GetNtProcessInfo.aspx- 这并不理想,因为它“不支持”直接从NTDLL 结构,但我会忍受它。感谢大家的建议。
UPDATE 2: I managed through more Googling to dig up a C version that does not use C++ code, and is a little more direct/concisely pointed toward this problem. See http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/for details.
更新 2:我通过更多的谷歌搜索来挖掘一个不使用 C++ 代码的 C 版本,并且更直接/简洁地指向这个问题。有关详细信息,请参阅http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/。
Thanks!
谢谢!
采纳答案by Jay
To answer my own question, I finally found a CodeProject solution that does exactly what I'm looking for:
为了回答我自己的问题,我终于找到了一个 CodeProject 解决方案,它完全符合我的要求:
http://www.codeproject.com/KB/threads/GetNtProcessInfo.aspx
http://www.codeproject.com/KB/threads/GetNtProcessInfo.aspx
As @Reuben already pointed out, you can use NtQueryProcessInformationto retrieve this information. Unfortuantely it's not a recommended approach, but given the only other solution seems to be to incur the overhead of a WMI query, I think we'll take this approach for now.
正如@Reuben 已经指出的那样,您可以使用NtQueryProcessInformation来检索此信息。不幸的是,这不是推荐的方法,但考虑到唯一的其他解决方案似乎是产生 WMI 查询的开销,我认为我们现在将采用这种方法。
Note that this seems to not work if using code compiled from 32bit Windows on a 64bit Windows OS, but since our modules are compiled from source on the target that should be OK for our purposes. I'd rather use this existing code and should it break in Windows 7 or a later date, we can look again at using WMI. Thanks for the responses!
请注意,如果在 64 位 Windows 操作系统上使用从 32 位 Windows 编译的代码,这似乎不起作用,但由于我们的模块是从目标上的源代码编译的,这对我们的目的来说应该没问题。我宁愿使用现有的代码,如果它在 Windows 7 或更高版本中出现问题,我们可以再次查看使用 WMI。感谢您的回复!
UPDATE: A more concise and C only (as opposed to C++) version of the same technique is illustrated here:
更新:此处说明了相同技术的更简洁且仅限 C(与 C++ 相对)的版本:
http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
回答by Ironicnet
The cached solution: 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
缓存解决方案: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
Also: http://mail.python.org/pipermail/python-win32/2007-December/006498.html
另外: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
回答by Giampaolo Rodolà
By using psutil ( https://github.com/giampaolo/psutil):
通过使用 psutil ( https://github.com/giampaolo/psutil):
>>> import psutil, os
>>> psutil.Process(os.getpid()).cmdline()
['C:\Python26\python.exe', '-O']
>>>
回答by reuben
The WMI approach mentioned in another response is probably the most reliableway of doing this. Looking through MSDN, I spotted what looks like another possible approach; it's documented, but its not clear whether it's fully supported. In MSDN's language, it--
在另一个响应中提到的 WMI 方法可能是最可靠的方法。通过 MSDN,我发现了另一种可能的方法;它已记录在案,但尚不清楚它是否得到完全支持。用 MSDN 的语言来说,它——
may be altered or unavailable in future versions of Windows...
在 Windows 的未来版本中可能会更改或不可用...
In any case, provided that your process has the right permissions, you should be able to call NtQueryProcessInformation
with a ProcessInformationClass
of ProcessBasicInformation
. In the returned PROCESS_BASIC_INFORMATION
structure, you should get back a pointer to the target process's process execution block(as field PebBaseAddress
). The ProcessParameters
field of the PEB will give you a pointer to an RTL_USER_PROCESS_PARAMETERS
structure. The CommandLine
field of that structure will be a UNICODE_STRING
structure. (Be careful not too make too many assumptions about the string; there are no guarantees that it will be NULL-terminated, and it's not clear whether or not you'll need to strip off the name of the executed application from the beginning of the command line.)
在任何情况下,只要您的进程具有正确的权限,您应该能够NtQueryProcessInformation
使用ProcessInformationClass
of进行调用ProcessBasicInformation
。在返回的PROCESS_BASIC_INFORMATION
结构中,您应该返回一个指向目标进程的进程执行块的指针(作为字段PebBaseAddress
)。ProcessParameters
PEB的字段将为您提供指向RTL_USER_PROCESS_PARAMETERS
结构的指针。该CommandLine
结构的字段将是一个UNICODE_STRING
结构。(注意不要对字符串做太多假设;不能保证它会以 NULL 结尾,并且不清楚是否需要从字符串的开头去掉已执行应用程序的名称命令行。)
I haven't tried this approach--and as I mentioned above, it seems a bit... iffy (read: non-portable)--but it might be worth a try. Best of luck...
我还没有尝试过这种方法——正如我上面提到的,它似乎有点......不确定(阅读:不可移植)——但它可能值得一试。祝你好运...
回答by Ana Betts
If you aren't the parent of these processes, then this is not possible using documented functions :( Now, if you're the parent, you can do your CreateRemoteThread trick, but otherwise you will almost certainly get Access Denied unless your app has admin rights.
如果你不是这些进程的父进程,那么使用文档化函数是不可能的:( 现在,如果你是父进程,你可以执行你的 CreateRemoteThread 技巧,但否则你几乎肯定会被拒绝访问,除非你的应用程序有管理员权限。