2010-11-14 2 views
3

В batchscript мне нужно получить список идентификаторов процессов с заданным двоичным путем C:\path\to\binary.exe. В Linux я могу просто сделать pidof /path/to/binary.Что такое эквивалент Windows «pidof» от Linux?

Есть ли исполняемый файл Win32, который делает то же самое, поддерживаемый WinXP Home to Win7 (список задач не работает)?

Пакет, который включает это, должен быть портативным, поэтому загрузка 10 МБ - это не то, что я ищу.

Есть ли функция C, которая делает это и поддерживается WinXP для Win7? Примечание. Я хочу сопоставить путь процесса, а не имя файла, которое может быть использовано и в других приложениях.

ответ

1

API-интерфейсы Toolhelp можно использовать для перечисления процессов, получения полного пути и сравнения его с требуемым именем процесса. Вам нужно пройти список модулей для каждого процесса. Первым модулем в списке является сам исполняемый файл процесса. Вот пример кода:

int main(int argc, char* argv[]) 
{ 

    if(argc > 1) 
    { 
     printf("\nGetting PID of: %s\n", argv[1]); 
     HANDLE hProcSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
     if(INVALID_HANDLE_VALUE != hProcSnapshot) 
     { 
      PROCESSENTRY32 procEntry = {0}; 
      procEntry.dwSize = sizeof(PROCESSENTRY32); 
      if(::Process32First(hProcSnapshot, &procEntry)) 
      { 
       do 
       { 
        HANDLE hModSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, procEntry.th32ProcessID); 
        if(INVALID_HANDLE_VALUE != hModSnapshot) 
        { 
         MODULEENTRY32 modEntry = {0}; 
         modEntry.dwSize = sizeof(MODULEENTRY32); 
         if(Module32First(hModSnapshot, &modEntry)) 
         { 
          if(0 == stricmp(argv[1], modEntry.szExePath)) 
          { 
           printf("\nPID: %ld\n", procEntry.th32ProcessID); 
           ::CloseHandle(hModSnapshot); 
           break; 
          } 
         } 
         ::CloseHandle(hModSnapshot); 
        } 
       } 
       while(::Process32Next(hProcSnapshot, &procEntry)); 
      } 
      ::CloseHandle(hProcSnapshot); 
     } 
    } 
    return 0; 
}
+0

Спасибо, это именно то, что мне нужно. Я видел '::' еще раз, это что-то вроде C++? Теперь я попытаюсь заставить его работать с именами Unicode, например, с китайцами. – Lekensteyn

+0

С небольшой модификацией он работает для [всех процессов] (http://forum.sysinternals.com/listing-processes-and-finding-executable_topic6595_post26001.html#26001). Он также работает теперь для специальных персонажей, таких как китайский. Чтобы это работало, система должна была быть китайской, иначе она показывала бы '?'. – Lekensteyn

1

PowerShell может решить ваши проблемы, если он загружен в Win 7 и доступен для загрузки на других ОС.

param($fileName) 
Get-Process | where -FilterScript {$_.MainModule.FileName -eq $fileName} 

Этот сценарий получит один параметр, имя файла, который вы ищете, и он будет выводить имя файла его исполняемого файла.

Вы можете назвать это из файла битой, выполнив:

-command "PowerShell & {Get-Process | где -FilterScript {$ _ MainModule.FileName -eq% FILENAME%}."

+0

Я хотел бы иметь его портативным, не устанавливая десятки вещей. Спасибо за ваш ответ. – Lekensteyn

+0

Достаточно справедливо. Имейте в виду, что Powershell - это только одно, а загрузка - 5 МБ для Windows Vista и 1.6 МБ для Windows XP. Он также встроен в выигрыш 7. Источник: http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx –

+0

Не так ли в обратном направлении от того, что спросил ОП? Он хочет знать, какие pids открыты в данном исполняемом файле, а не какой исполняемый файл открыт на заданном pid. –

1

Вы можете написать небольшое приложение C#, которое сначала вызывает Process.GetProcessesByName(String), затем перейдите по результатам и распечатайте свойство Id каждого из них, когда MainModule. FileName соответствует пути, который вы ищете.

+0

Это возвращает только имя процесса, например GetModuleFileName или CreateToolhelp32Snapshot. Есть ли функция, которая работает от WinXP до Win7 и возвращает путь? – Lekensteyn

+0

@Lekensteyn - вы правы, я отредактировал ответ на путь, возвращающийся. – rkellerm

4

wmic.exe доступна на XP, Vista и 7, и может это сделать. Однако он не поставляется с Windows XP Home Edition.

wmic process where ExecutablePath='C:\\windows\\system32\\notepad.exe' get ProcessId 

Если вы хотите поддержать для Windows XP Home тоже можно использовать EnumProcess и GetModuleFileNameEx. Недостатком здесь является то, что вы не сможете запрашивать имена процессов, запущенных другим пользователем, если вы не работаете как администратор. QueryFullProcessImageName, вероятно, сделает трюк здесь, но это Vista +.

Если этого недостаточно, вам понадобится Process32First (код swatkat). Для каждого процесса вам необходимо позвонить Module32First, а затем получить MODULEENTRY32->szExePath. Обратите внимание, что даже это не полностью переносимо и не будет работать на x64, где вам понадобится QueryFullProcessImageName.

Смежные вопросы