Чтение аргументов командной строки другого процесса (код Win32 C) - PullRequest
9 голосов
/ 14 января 2009

Мне нужно иметь возможность перечислять аргументы командной строки (если есть), передаваемые другим запущенным процессам. У меня уже есть PID запущенных процессов в системе, поэтому в основном мне нужно определить аргументы, передаваемые процессу с данным PID XXX .

Я работаю над основной частью модуля Python для управления процессами . Код написан как расширение Python на C и будет упакован в библиотеку Python более высокого уровня. Цель этого проекта - избежать зависимости от сторонних библиотек, таких как расширения pywin32, или от уродливых хаков, таких как вызов ps или taskkill в командной строке, поэтому я ищу способ сделать это в C-коде.

Я прогуглил это и нашел несколько кратких предложений по использованию CreateRemoteThread () , чтобы внедрить себя в другой процесс, затем запустить GetCommandLine () , но я надеялся, что кто-то есть примеры рабочих кодов и / или лучшие предложения.

ОБНОВЛЕНИЕ : Я нашел полностью работающий демонстрационный код и решение, использующее NtQueryProcessInformation для CodeProject: http://www.codeproject.com/KB/threads/GetNtProcessInfo.aspx - Это не идеально, так как "не поддерживается" для отбора информации непосредственно из NTDLL структуры, но я буду жить с этим. Спасибо всем за предложения.

ОБНОВЛЕНИЕ 2 : мне удалось с помощью большего количества Googling выкопать версию C, которая не использует код C ++, и немного более прямо / кратко указывает на эту проблему. Подробнее см. http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/.

Спасибо!

Ответы [ 5 ]

6 голосов
/ 15 января 2009

Чтобы ответить на мой собственный вопрос, я наконец нашел решение CodeProject, которое делает именно то, что я ищу:

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

Как уже указывал @Reuben, вы можете использовать NtQueryProcessInformation для получения этой информации. К сожалению, это не рекомендуемый подход, но, учитывая, что единственное другое решение, похоже, связано с накладными расходами запроса WMI, я думаю, что сейчас мы воспользуемся этим подходом.

Обратите внимание, что это, похоже, не работает, если использовать код, скомпилированный из 32-битной Windows, в 64-битной ОС Windows, но так как наши модули скомпилированы из исходного кода на целевой системе, это должно быть в порядке для наших целей. Я предпочел бы использовать этот существующий код, и если он выйдет из строя в Windows 7 или более поздней версии, мы можем еще раз взглянуть на использование WMI. Спасибо за ответы!

ОБНОВЛЕНИЕ : более краткая и только C (в отличие от C ++) версия того же метода показана здесь:

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

5 голосов
/ 14 января 2009

Кэшированное решение: 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
3 голосов
/ 20 ноября 2010

Используя psutil (https://github.com/giampaolo/psutil):

>>> import psutil, os
>>> psutil.Process(os.getpid()).cmdline()
['C:\\Python26\\python.exe', '-O']
>>> 
2 голосов
/ 14 января 2009

Подход WMI, упомянутый в другом ответе, является, вероятно, наиболее надежным способом сделать это. Просматривая MSDN, я обнаружил, что выглядит как еще один возможный подход; это задокументировано, но не ясно, поддерживается ли оно полностью. На языке MSDN это -

может быть изменен или недоступен в будущие версии Windows ...

В любом случае, при условии, что у вашего процесса есть необходимые разрешения, вы должны иметь возможность вызывать NtQueryProcessInformation с ProcessInformationClass из ProcessBasicInformation. В возвращенной структуре PROCESS_BASIC_INFORMATION вы должны получить указатель на блок выполнения процесса целевого процесса (как поле PebBaseAddress). Поле ProcessParameters PEB даст вам указатель на структуру RTL_USER_PROCESS_PARAMETERS. Поле CommandLine этой структуры будет иметь структуру UNICODE_STRING. (Будьте осторожны, не делайте слишком много предположений о строке; нет никаких гарантий, что она будет завершена NULL, и неясно, нужно ли вам удалять имя исполняемого приложения с начала командная строка.)

Я не пробовал этот подход - и, как я упоминал выше, он кажется немного ... ненадежным (читай: непереносимым) - но, возможно, стоит попробовать. Желаем удачи ...

0 голосов
/ 14 января 2009

Если вы не являетесь родителем этих процессов, то это невозможно с помощью документированных функций :( Теперь, если вы родитель, вы можете выполнить трюк CreateRemoteThread, но в противном случае вы почти наверняка получите отказ в доступе, если Ваше приложение имеет права администратора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...