2010-11-14 69 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上无法正常工作。

相关问题