Мне нужно иметь возможность перечислить аргументы командной строки (если есть), переданные другим запущенным процессам. У меня уже есть 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: Мне удалось через больше поисков в Google найти версию C, которая не использует код C++ и немного более прямо / лаконично указывает на эту проблему. Подробнее см. http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/.
Спасибо!






Если вы не являетесь родителем этих процессов, то это невозможно с использованием документированных функций :( Теперь, если вы родитель, вы можете выполнить свой трюк CreateRemoteThread, но в противном случае вы почти наверняка получите отказ в доступе, если ваше приложение не имеет права администратора.
Кешированное решение: 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-De 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, которые мы также не хотим требовать от пользователя.
Вы можете вызвать WMI из C через его COM-интерфейс, хотя это не самый элегантный код.
@Rob - это правда ... это было бы серьезными накладными расходами для этой, казалось бы, простой задачи, но похоже, что у меня не так много вариантов.
Подход WMI, упомянутый в другом ответе, вероятно, является наиболее подходящим способом надежный для этого. Просматривая MSDN, я обнаружил, что похоже на другой возможный подход; он задокументирован, но неясно, полностью ли он поддерживается. На языке MSDN это -
may be altered or unavailable in future versions of Windows...
В любом случае, при условии, что у вашего процесса есть необходимые разрешения, вы должны иметь возможность вызывать NtQueryProcessInformation с ProcessInformationClass из ProcessBasicInformation. В возвращенной структуре PROCESS_BASIC_INFORMATION вы должны получить обратно указатель на блок выполнения процесса целевого процесса (как поле PebBaseAddress). Поле ProcessParameters PEB даст вам указатель на структуру RTL_USER_PROCESS_PARAMETERS. Поле CommandLine этой структуры будет структурой UNICODE_STRING. (Будьте осторожны, не делайте слишком много предположений о строке; нет никаких гарантий, что она будет завершена NULL, и неясно, нужно ли вам удалять имя исполняемого приложения с начала командная строка.)
Я не пробовал этот подход - и, как я уже упоминал выше, он кажется немного ... сомнительным (читай: непереносимым) - но, возможно, стоит попробовать. Удачи...
Я видел это и чувствовал то же самое, что и вы - это казалось шатким, но демонстрация CodeProject, которую я обнаружил, отлично работает даже в Vista, поэтому я все равно буду использовать это. См. Ссылку CodeProject для рабочего кода.
Чтобы ответить на свой вопрос, я наконец нашел решение 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/
Используя psutil (https://github.com/giampaolo/psutil):
>>> import psutil, os
>>> psutil.Process(os.getpid()).cmdline()
['C:\\Python26\\python.exe', '-O']
>>>
Теперь у меня есть код в модуле, который получит права SeDebug, если это возможно, поэтому, если они являются пользователем Admin, у нас должны быть необходимые привилегии, верно?