2010-11-14 89 views
3

在批處理腳本中,我需要獲取給定二進制路徑C:\path\to\binary.exe的進程ID列表。 在Linux中,我可以做pidof /path/to/binary什麼是Windows的「pidof」等同於Linux?

是否有一個Win32可執行文件,它支持從WinXP Home到Win7(tasklist不起作用)?

包含這個的軟件包必須是可移植的,所以10MB的下載並不是我正在尋找的。

是否有C函數可以這樣做是從WinXP到Win7的支持嗎?注意:我想匹配一個進程路徑,而不是其他應用程序可以使用的文件名。

回答

1

您可以使用Toolhelp API枚舉進程,獲取其完整路徑並將其與所需的進程名稱進行比較。您需要遍歷每個進程的模塊列表。列表中的第一個模塊是進程可執行文件本身。下面是一個示例代碼:

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 2010-11-14 11:03:27

+0

稍作修改,適用於[所有進程](http://forum.sysinternals.com/listing-processes-and-finding-executable_topic6595_post26001.html#26001)。它現在也適用於特殊字符,如中文。爲了達到這個目的,系統必須是中文的,否則會顯示「?」。 – Lekensteyn 2010-11-14 14:24:07

1

PowerShell可以解決您的問題,如果是在Win 7中安裝,並且可以在其他操作系統上下載。

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

此腳本將接收一個參數,您正在查找的文件名,它將輸出其可執行文件的文件名。

您可以通過執行從一個bat文件調用此:

PowerShell的-Command 「& {獲取進程|其中-FilterScript {$ _ MainModule.FileName當量%FILENAME%}。」

+0

我想擁有它便攜式,沒有安裝幾十個東西。無論如何感謝您的回答。 – Lekensteyn 2010-11-14 09:50:42

+0

夠公平的。請記住,Powershell只是一件事,Windows Vista下載量爲5MB,Windows XP下載量爲1.6MB。它也內置到勝利7.資料來源:http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx – 2010-11-14 09:54:24

+0

這不正是OP的要求是什麼?他想知道給定可執行文件上的哪些pid是打開的,而不是在給定的pid上打開哪個可執行文件。 – 2010-11-14 10:21:21

1

您可以編寫一個小型C#應用程序,它首先調用Process.GetProcessesByName(String),然後查看結果並在MainModule時打印每個應用程序的Id屬性。 FileName等於您正在查找的路徑。

+0

僅返回像GetModuleFileName或CreateToolhelp32Snapshot這樣的進程名稱。有沒有一個從WinXP到Win7的函數,並返回一個路徑? – Lekensteyn 2010-11-14 09:54:05

+0

@Lekensteyn - 你是對的,我編輯了路徑retreiving的答案。 – rkellerm 2010-11-14 10:15:17

4

了Wmic.exe可在XP,Vista和Windows 7,可以做到這一點。但是,它不附帶Windows XP Home Edition。

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

如果您想爲Windows XP家庭支持也一樣,你可以使用EnumProcessGetModuleFileNameEx。這裏的缺點是,如果您沒有以管理員身份運行,您將無法查詢其他用戶正在運行的進程的名稱。 QueryFullProcessImageName可能會在這裏做的伎倆,但它是Vista +。

如果這還不夠,您需要Process32First(swatkat的代碼)。對於每個過程,您需要致電Module32First,然後獲得MODULEENTRY32->szExePath。請注意,即使這不是完全可移植的,並且在需要QueryFullProcessImageName的x64上無法正常工作。

相關問題