无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
查看: 2138|回复: 20
打印 上一主题 下一主题

[原创] 统计同名进程

  [复制链接]
跳转到指定楼层
1#
发表于 2023-9-28 19:16:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为了解决这个问题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

评分

参与人数 1无忧币 +5 收起 理由
yyz2191958 + 5 很给力!

查看全部评分

2#
发表于 2023-9-28 19:23:52 | 只看该作者
楼主的技术含量很高  强烈支持
回复

使用道具 举报

3#
发表于 2023-9-28 19:45: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
*************************************
不知道问题出现在哪里?

点评

这和之前哪个返回格式不一样,for /f "tokens=2 delims=:" %%a in  详情 回复 发表于 2023-9-28 19:54
回复

使用道具 举报

4#
 楼主| 发表于 2023-9-28 19:54:30 | 只看该作者
yyz2191958 发表于 2023-9-28 19:45
这个批处理检查成功:
::【PE 下检测同名进程几个】
@echo off

这和之前那个返回格式不一样,for /f "tokens=2 delims=:" %%a in

点评

成功了 非常感谢  详情 回复 发表于 2023-9-28 20:05

评分

参与人数 1无忧币 +5 收起 理由
yyz2191958 + 5 很给力!

查看全部评分

回复

使用道具 举报

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

成功了  非常感谢
回复

使用道具 举报

6#
发表于 2023-9-28 20:11:22 | 只看该作者
上面高手很多啊。这个统计有什么用?

点评

有一些时候需要  详情 回复 发表于 2023-9-28 20:47
基本没什么用,针对链接问题的。  详情 回复 发表于 2023-9-28 20:14
回复

使用道具 举报

7#
 楼主| 发表于 2023-9-28 20:14:57 | 只看该作者
zwmfyy 发表于 2023-9-28 20:11
上面高手很多啊。这个统计有什么用?

基本没什么用,针对链接问题的。
回复

使用道具 举报

8#
发表于 2023-9-28 20:47:07 | 只看该作者
zwmfyy 发表于 2023-9-28 20:11
上面高手很多啊。这个统计有什么用?

有一些时候需要
回复

使用道具 举报

9#
发表于 2023-9-28 21:16:21 | 只看该作者
谢谢分享
回复

使用道具 举报

10#
发表于 2023-9-28 22:52:34 | 只看该作者
谢谢分享
回复

使用道具 举报

11#
发表于 2023-9-28 23:47:13 | 只看该作者
感谢分享
回复

使用道具 举报

12#
发表于 2023-9-29 07:44:21 | 只看该作者
谢谢分享!
回复

使用道具 举报

13#
发表于 2023-9-29 10:02:54 | 只看该作者
谢谢分享
回复

使用道具 举报

14#
发表于 2023-9-29 11:39:23 | 只看该作者

谢谢分享
回复

使用道具 举报

15#
发表于 2023-9-29 16:08:56 | 只看该作者
谢谢,学习了!
回复

使用道具 举报

16#
发表于 2023-9-29 17:09:00 | 只看该作者
谢谢分享
回复

使用道具 举报

17#
发表于 2023-10-1 16:15:40 | 只看该作者
感谢楼主更新分享
回复

使用道具 举报

18#
发表于 2023-10-1 16:31:43 | 只看该作者
        很给力!
回复

使用道具 举报

19#
发表于 2023-10-1 16:36:41 | 只看该作者
谢谢分享
回复

使用道具 举报

20#
发表于 2023-10-30 08:49:03 | 只看该作者
谢谢分享
回复

使用道具 举报

21#
发表于 2024-2-28 16:29:40 | 只看该作者
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-9-20 14:47

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表