7.5 通過API判斷進程狀態

進程狀態的判斷包括驗證進程是否存在,實現方法是通過枚舉系統內的所有進程信息,並將該進程名通過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 許可協議。轉載請註明出處!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章