无忧启动论坛

标题: 统计同名进程 [打印本页]

作者: batche    时间: 2023-9-28 19:16
标题: 统计同名进程
为了解决这个问题http://bbs.c3.wuyou.net/forum.php?mod=viewthread&tid=437483,我前两天写了个程序,今天又给它优化了一下,可选区分大小写,支持通配符,cmd窗口无参数运行程序即可看使用方法。
  1. #include <windows.h>
  2. #include <tlhelp32.h>
  3. #include <stdio.h>
  4. #include <stdbool.h>
  5. #include <string.h>

  6. typedef struct {
  7.         char name[MAX_PATH];
  8.         int count;
  9. } ProcessInfo;

  10. bool WildcardMatch(const char *, const char *, bool);

  11. int GetProcessCount(const char *processName, bool caseSensitive, ProcessInfo *processes, int maxProcesses) {
  12.         int count = 0;
  13.         HANDLE hProcessSnap;
  14.         PROCESSENTRY32 pe32;

  15.         hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  16.         if (hProcessSnap == INVALID_HANDLE_VALUE) {
  17.                 fprintf(stderr, "CreateToolhelp32Snapshot 失败。错误:%lu\n", GetLastError());
  18.                 return -1;
  19.         }

  20.         pe32.dwSize = sizeof(PROCESSENTRY32);

  21.         if (Process32First(hProcessSnap, &pe32)) {
  22.                 do {
  23.                         bool match = false;
  24.                         if (caseSensitive) {
  25.                                 if (strcmp(processName, pe32.szExeFile) == 0 || WildcardMatch(processName, pe32.szExeFile, caseSensitive)) {
  26.                                         match = true;
  27.                                 }
  28.                         } else {
  29.                                 char processNameLower[MAX_PATH];
  30.                                 strcpy(processNameLower, processName);
  31.                                 strlwr(processNameLower);
  32.                                 char pe32ExeFileLower[MAX_PATH];
  33.                                 strcpy(pe32ExeFileLower, pe32.szExeFile);
  34.                                 strlwr(pe32ExeFileLower);
  35.                                 if (strcmp(processNameLower, pe32ExeFileLower) == 0
  36.                                         || WildcardMatch(processNameLower, pe32ExeFileLower, caseSensitive)) {
  37.                                         match = true;
  38.                                 }
  39.                         }

  40.                         if (match) {
  41.                                 bool found = false;
  42.                                 for (int i = 0; i < count; i++) {
  43.                                         if (strcmp(processes[i].name, pe32.szExeFile) == 0) {
  44.                                                 processes[i].count++;
  45.                                                 found = true;
  46.                                                 break;
  47.                                         }
  48.                                 }
  49.                                 if (!found && count < maxProcesses) {
  50.                                         strncpy(processes[count].name, pe32.szExeFile, MAX_PATH - 1);
  51.                                         processes[count].name[MAX_PATH - 1] = '\0';
  52.                                         processes[count].count = 1;
  53.                                         count++;
  54.                                 }
  55.                         }
  56.                 } while (Process32Next(hProcessSnap, &pe32));
  57.         }

  58.         CloseHandle(hProcessSnap);
  59.         return count;
  60. }

  61. int main(int argc, char *argv[]) {
  62.         if (argc < 2) {
  63.                 fprintf(stderr, "用法:%s <进程名称> [/c (区分大小写)]\n"
  64.                         "支持通配符#和;,与cmd的*和?用法相同,不用*和?是因为在cmd中执行会被解析\n", argv[0]);
  65.                 return 1;
  66.         }

  67.         const char *processName = argv[1];
  68.         bool caseSensitive = false;

  69.         if (argc == 3 && strcmp(argv[2], "/c") == 0) {
  70.                 caseSensitive = true;
  71.         }

  72.         const int maxProcesses = 100;
  73.         ProcessInfo processes[maxProcesses];
  74.         int count = GetProcessCount(processName, caseSensitive, processes, maxProcesses);

  75.         if (count == -1) {
  76.                 fprintf(stderr, "获取进程数量失败。\n");
  77.         } else {
  78.                 int total = 0;
  79.                 for (int i = 0; i < count; i++) {
  80.                         printf("%-30s:%d\n", processes[i].name, processes[i].count);
  81.                         total += processes[i].count;
  82.                 }

  83.                 if (count != 1) {
  84.                         printf("%-30s:%d", argv[1], total);
  85.                 }
  86.         }

  87.         return 0;
  88. }

  89. bool WildcardMatch(const char *pattern, const char *string, bool caseSensitive) {
  90.         if (*pattern == '\0' && *string == '\0') {
  91.                 return true;
  92.         }

  93.         if (*pattern == '#' && *(pattern + 1) != '\0' && *string == '\0') {
  94.                 return false;
  95.         }

  96.         if (*pattern == ';' || (caseSensitive ? (*pattern == *string) : (tolower(*pattern) == tolower(*string)))) {
  97.                 return WildcardMatch(pattern + 1, string + 1, caseSensitive);
  98.         }

  99.         if (*pattern == '#') {
  100.                 return WildcardMatch(pattern + 1, string, caseSensitive) || WildcardMatch(pattern, string + 1, caseSensitive);
  101.         }

  102.         return false;
  103. }
复制代码


源码及程序下载:pan.baidu.com/s/1L7MYeSsJGlxENVQx2S08Mw?pwd=xfxi
作者: yyz2191958    时间: 2023-9-28 19:23
楼主的技术含量很高  强烈支持
作者: yyz2191958    时间: 2023-9-28 19:45
这个批处理检查成功:
::【PE 下检测同名进程几个】
@echo off
processn.exe notepad2.exe
pause >nul
exit
*******************************************
下面的批处理检查不成功(无论进程多少或者无,都显示:大于等于2个进程):
::【(大于等于2个进程,跳到 :A)(少于2个进程,继续检测)】
@echo off

:B
echo 少于2个进程
for /f %%a in ('processn.exe Notepad2.exe') do if %%a gtr 1 goto :A
ping -n 3 127.0.0.1 >nul
cls
goto :B

:A
cls
echo 大于等于2个进程
pause
*************************************
不知道问题出现在哪里?
作者: batche    时间: 2023-9-28 19:54
yyz2191958 发表于 2023-9-28 19:45
这个批处理检查成功:
::【PE 下检测同名进程几个】
@echo off

这和之前那个返回格式不一样,for /f "tokens=2 delims=:" %%a in
作者: yyz2191958    时间: 2023-9-28 20:05
batche 发表于 2023-9-28 19:54
这和之前那个返回格式不一样,for /f "tokens=2 delims=:" %%a in

成功了  非常感谢
作者: zwmfyy    时间: 2023-9-28 20:11
上面高手很多啊。这个统计有什么用?
作者: batche    时间: 2023-9-28 20:14
zwmfyy 发表于 2023-9-28 20:11
上面高手很多啊。这个统计有什么用?

基本没什么用,针对链接问题的。
作者: yyz2191958    时间: 2023-9-28 20:47
zwmfyy 发表于 2023-9-28 20:11
上面高手很多啊。这个统计有什么用?

有一些时候需要
作者: nathan6498    时间: 2023-9-28 21:16
谢谢分享
作者: yc2428    时间: 2023-9-28 22:52
谢谢分享
作者: Fastwingo    时间: 2023-9-28 23:47
感谢分享
作者: dx163    时间: 2023-9-29 07:44
谢谢分享!
作者: awan8850    时间: 2023-9-29 10:02
谢谢分享
作者: 黑鹰99    时间: 2023-9-29 11:39

谢谢分享
作者: tanglf    时间: 2023-9-29 16:08
谢谢,学习了!
作者: 524280981    时间: 2023-9-29 17:09
谢谢分享
作者: BEIKING    时间: 2023-10-1 16:15
感谢楼主更新分享
作者: 创新科技2015    时间: 2023-10-1 16:31
        很给力!
作者: 创新科技2015    时间: 2023-10-1 16:36
谢谢分享
作者: 无犹启动    时间: 2023-10-30 08:49
谢谢分享
作者: 无犹启动    时间: 2024-2-28 16:29
谢谢分享




欢迎光临 无忧启动论坛 (http://wuyou.net/) Powered by Discuz! X3.3