7.5 通过API判断进程状态

简介: 进程状态的判断包括验证进程是否存在,实现方法是通过枚举系统内的所有进程信息,并将该进程名通过`CharLowerBuff`转换为小写,当转换为小写模式后则就可以通过使用`strcmp`函数对比,如果发现继承存在则返回该进程的PID信息,否则返回-1。

进程状态的判断包括验证进程是否存在,实现方法是通过枚举系统内的所有进程信息,并将该进程名通过CharLowerBuff转换为小写,当转换为小写模式后则就可以通过使用strcmp函数对比,如果发现继承存在则返回该进程的PID信息,否则返回-1。

int GetProcessStatus(const char *procressName)
{
   
  char pName[MAX_PATH];
  strcpy(pName, procressName);                           // 拷贝数组
  CharLowerBuff(pName, MAX_PATH);                        // 将名称转换为小写

  PROCESSENTRY32 currentProcess;                                    // 存放快照进程信息的一个结构体
  currentProcess.dwSize = sizeof(currentProcess);                   // 在使用这个结构之前,先设置它的大小
  HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 给系统内的所有进程拍一个快照

  if (INVALID_HANDLE_VALUE != hProcess)
  {
   
    BOOL bMore = Process32First(hProcess, &currentProcess);
    while (bMore)
    {
   
      CharLowerBuff(currentProcess.szExeFile, MAX_PATH);        // 将进程名转换为小写
      if (strcmp(currentProcess.szExeFile, pName) == 0)         // 比较是否存在此进程
      {
   
        CloseHandle(hProcess);
        return currentProcess.th32ProcessID;
      }
      bMore = Process32Next(hProcess, &currentProcess);
    }
    CloseHandle(hProcess);
  }
  return -1;
}

有时候我们需要判断自身进程是否被重复运行了,这种需求在软件开发中经常会遇到,通常该需求可以使用CreateMutex创建或打开一个互斥量对象(Mutex Object),在多线程/进程的环境下,互斥量可用于控制对某个共享资源的访问。其函数声明如下:

HANDLE CreateMutex(
  LPSECURITY_ATTRIBUTES lpMutexAttributes,
  BOOL                  bInitialOwner,
  LPCTSTR               lpName
);

其中,lpMutexAttributes 是用于指定新创建的互斥量的安全描述符的指针;bInitialOwner 表示一个布尔值,指定初始所有权标记,为 TRUE 表示调用线程将拥有该互斥量,否则表示它不属于调用线程;lpName 是可选的,用于命名互斥体,以使得其他线程或者进程可以通过这个名字来打开该互斥量对象。

CreateMutex 函数会返回一个内核对象句柄,用于在之后对该互斥体进行引用和操作,通过使用互斥体可以很容易的实现对进程运行状态的判断。

#include <Windows.h>
#include <stdio.h>

// 判断是否重复运行
BOOL IsAlreadyRun()
{
   
  HANDLE hMutex = NULL;
  hMutex = CreateMutex(NULL, FALSE, "RUN");
  if (hMutex)
  {
   
    if (ERROR_ALREADY_EXISTS == GetLastError())
      return TRUE;
  }
  return FALSE;
}

int main(int argc, const char * argv[])
{
   
  if (IsAlreadyRun() == TRUE)
    printf("重复运行 \n");
  else
    printf("没有重复运行 \n");

  system("pause");
  return 0;
}

对进程位数的判断也是有必要的,通常在Windows系统下进程位数的有多种方法实现,第一种方式GetNativeSystemInfo调用该函数并判断函数内的特定成员,即可得到当前系统是否为64位,当然通过使用Is64BitPorcess函数也可实现对特定进程的判断,此方式实现原理是通过调用IsWow64Process函数实现;

#include <stdio.h>
#include <Windows.h>
#include <tlhelp32.h>

// 判断自身系统是否为64位
BOOL IsSelf64bitSystem()
{
   
  SYSTEM_INFO si;
  GetNativeSystemInfo(&si);
  if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
    si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
    return TRUE;
  else
    return FALSE;
}

// 判断指定进程是否为64位进程
BOOL Is64BitPorcess(DWORD dwProcessID)
{
   
  HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessID);
  if (hProcess)
  {
   
    typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
    LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)
      GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process");
    if (NULL != fnIsWow64Process)
    {
   
      BOOL bIsWow64 = FALSE;
      fnIsWow64Process(hProcess, &bIsWow64);
      CloseHandle(hProcess);
      if (bIsWow64)
        return FALSE;
      else
        return TRUE;
    }
  }
  return FALSE;
}

int main(int argc, char *argv[])
{
   
  PROCESSENTRY32 pe32;
  pe32.dwSize = sizeof(pe32);

  HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  BOOL bMore = Process32First(hProcessSnap, &pe32);

  while (bMore)
  {
   
    printf("进程PID: %5d 是否64位: %d 进程名称: %s\n",
      pe32.th32ProcessID, Is64BitPorcess(pe32.th32ProcessID), pe32.szExeFile);

    bMore = Process32Next(hProcessSnap, &pe32);
  }
  system("pause");
  return 0;
}

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/7821bd48.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

目录
相关文章
|
11月前
|
安全 API
7.4 通过API枚举进程权限
GetTokenInformation 用于检索进程或线程的令牌(Token)信息。Token是一个数据结构,其包含有关进程或线程的安全上下文,代表当前用户或服务的安全标识符和权限信息。GetTokenInformation函数也可以用来获取这些安全信息,通常用于在运行时检查某个进程或线程的权限或安全信息。
87 1
|
9月前
|
存储 SQL Shell
【OSTEP】Abstraction Process | 进程 | 虚拟化 | 进程API
【OSTEP】Abstraction Process | 进程 | 虚拟化 | 进程API
38 0
|
3月前
|
消息中间件 监控 安全
探究如何在Linux系统中修改进程资源限制:四种方法调整进程限制,让你的系统高效运行(包含应用层getrlimit和setrlimit API)
探究如何在Linux系统中修改进程资源限制:四种方法调整进程限制,让你的系统高效运行(包含应用层getrlimit和setrlimit API)
531 0
|
3月前
|
Java API 调度
Java多线程基础(线程与进程的区别,线程的创建方式及常用api,线程的状态)
Java多线程基础(线程与进程的区别,线程的创建方式及常用api,线程的状态)
70 0
Java多线程基础(线程与进程的区别,线程的创建方式及常用api,线程的状态)
|
11月前
|
API
7.3 通过API枚举进程
首先实现枚举当前系统中所有进程信息,枚举该进程的核心点在于使用`CreateToolhelp32Snapshot()`函数,该函数用于创建系统进程和线程快照,它可以捕获当前系统中进程和线程相关的信息(如PID、线程数量、线程ID等),在对这些信息进行处理后,可以获得很多有用的数据,如当前系统中所有正在执行的进程的信息列表,以及每个进程各自的详细信息(如CPU、内存占用量等)。
58 1
|
11月前
|
安全 API Windows
7.2 通过API创建新进程
创建新的进程是`Windows`程序开发的重要部分,它可以用于实现许多功能,例如进程间通信、并行处理等。其中,常用的三种创建进程的方式分别是`WinExec()`、`ShellExecute()`和`CreateProcessA()`,这三种创建进程的方式各有特点。如果需要创建简单进程或从其他程序启动新进程,可以使用`WinExec()`或`ShellExecute()`函数。如果需要对新进程进行更精细的配置,例如控制进程参数、指定安全级别、传递特定的命令和参数等,可以使用`CreateProcessA()`函数。
86 0
|
Unix Shell API
Unix 进程 API 介绍
Unix 进程 API 介绍
125 0
|
Java API 调度
Java多线程基础(线程与进程的区别,线程的创建方式及常用api,线程的状态)
每一个线程都是一个执行流,都按照自己的顺序执行自己的代码,多个线程之间“同时”(并发并行)的执行多份代码。Java中的线程是以轻量级进程来实现的。
Java多线程基础(线程与进程的区别,线程的创建方式及常用api,线程的状态)