RegNotifyChangeKeyValue 监控注册表变化

/
//RegMonitorClass.h
#pragma once

class CRegMonitorClass
{
public:
  //标准构析函数
  CRegMonitorClass();
  ~CRegMonitorClass();

protected:
  HKEY   m_hMonRegKey; //准备监视的键句柄
  HANDLE m_hMonThread; //监控线程
  HANDLE m_hExitEvent; //线程退出事件
  HANDLE m_hMonEvent;  //监控变化事件

#define _DbgPrintf TRACE
public: 
  virtual BOOL StopMonitor(); //停止监控
  virtual BOOL StartMonitor(HKEY hPrmKey, LPCTSTR szKey); //启动监控
  
protected:  
  virtual DWORD RegMonFunction(); //监控注册表功能函数 
  static DWORD CALLBACK RegMonThread(LPVOID lParam); //监控线程
};

 

/
//RegMonitorClass.cpp
#include "RegMonitorClass.h"
CRegMonitorClass::CRegMonitorClass()
{
  m_hMonRegKey = NULL;
  m_hExitEvent = NULL;
  m_hMonEvent = NULL;
  m_hMonThread = NULL;
}

CRegMonitorClass::~CRegMonitorClass()
{
  StopMonitor();
}

//停止监控
BOOL CRegMonitorClass::StopMonitor()
{
  if(m_hExitEvent)
  {
    SetEvent(m_hExitEvent);
  }
  if(m_hMonThread)
  {
    WaitForSingleObject(m_hMonThread, 2000);
    CloseHandle(m_hMonThread);
    m_hMonThread = NULL;
  }
  if(m_hExitEvent)
  {
    CloseHandle(m_hExitEvent);
    m_hExitEvent = NULL;
  }
  if(m_hMonEvent)
  {
    CloseHandle(m_hMonEvent);
    m_hMonEvent = NULL;
  }
  if(m_hMonRegKey)
  {
    RegCloseKey(m_hMonRegKey);
    m_hMonRegKey = NULL;
  }

  _DbgPrintf(_T("StopMonitor\n"));

  return TRUE;
}

//启动监控
//成功是返回TURE
BOOL CRegMonitorClass::StartMonitor(HKEY hPrmKey, LPCTSTR szKey)
{
  BOOL bRet = FALSE;
  StopMonitor();

  do
  {
    //打开注册表
    DWORD dwRet = RegOpenKeyEx(hPrmKey, szKey, 0, KEY_ALL_ACCESS, &m_hMonRegKey);
    if(dwRet != ERROR_SUCCESS || m_hMonRegKey == NULL)
    {
      _DbgPrintf(_T("RegOpenKeyEx failed %u\n"), dwRet);
      bRet = -1;
      break;
    }

    //创建退出事件
    if(m_hExitEvent == NULL)
    {
      m_hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    }
    if(m_hExitEvent == NULL)
    {
      _DbgPrintf(_T("Create exit Event failed %u\n"), GetLastError());
      bRet = -2;
      break;
    }

    //创建监控变化事件
    if(m_hMonEvent == NULL)
    {
      m_hMonEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    }
    if(m_hMonEvent == NULL)
    {
      _DbgPrintf(_T("Create monitor Event failed %u\n"), GetLastError());
      bRet = -3;
      break;
    }

    //启动监控线程
    if(m_hMonThread == NULL)
    {
      m_hMonThread = CreateThread(NULL, 0, RegMonThread, this, 0, NULL);
    }
    if(m_hMonThread == NULL)
    {
      _DbgPrintf(_T("CreateThread failed %u\n"), GetLastError());
      bRet = -4;
      break;
    }

    _DbgPrintf(_T("Start register monitor succeed\n"));

    bRet = TRUE;

  }while(0);

  //失败时关闭监控
  if(bRet <= 0)
  {
    StopMonitor();
  }

  return bRet;
}
  
//监控注册表功能函数
DWORD CRegMonitorClass::RegMonFunction()
{
  ASSERT(m_hMonEvent);
  ASSERT(m_hMonRegKey);
  ASSERT(m_hExitEvent);

  BOOL bEixtFlag = FALSE;
  while((!bEixtFlag))
  {
    //重置事件
    ResetEvent(m_hMonEvent);

    //注册事件
    DWORD dwRet = RegNotifyChangeKeyValue(m_hMonRegKey, 
      TRUE, REG_LEGAL_CHANGE_FILTER, m_hMonEvent, TRUE);

    if(dwRet != ERROR_SUCCESS)
    {
      TRACE(_T("RegNotifyChangeKeyValue failed %u\n"), dwRet);
      break;
    }

    //等待事件
    HANDLE hEventArray[] = {m_hExitEvent, m_hMonEvent};
    DWORD dwWait = WaitForMultipleObjects(2, hEventArray, FALSE, INFINITE);
    switch(dwWait)  
    {
    case(WAIT_OBJECT_0 + 0):  //exit event
      {
        bEixtFlag = 1;
        break;
      }
    case(WAIT_OBJECT_0 + 1): //done event
      {
        TRACE(_T("RegNotifyChangeKeyValue Notifyed!\n"));
        //这里添加处理

        break;
      }
    default: //unexpected
      {
        bEixtFlag = -1;
        TRACE(_T("WaitForMultipleObjects failed %u\n"), dwWait);
        break;
      }
    }
  }

  return 0;
}

//监控线程
DWORD CALLBACK CRegMonitorClass::RegMonThread(LPVOID lParam)
{
  CRegMonitorClass *pThis = (CRegMonitorClass *)lParam;
  __try
  {
    pThis->RegMonFunction();
  }
  __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
  {
    ASSERT(0);
  }
  return 0;
}

 

//启动监控示例
CRegMonitorClass m_RegMon;

void CDlg1Dlg::OnButton1() 
{
  m_RegMon.StartMonitor(HKEY_CURRENT_USER, _T("Software\\Test"));
}

 

要使用C++实现检测Windows注册表'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall'变化的通知回调,可以使用Windows API提供的注册表监视功能和消息循环机制。以下是一个示例代码: ```cpp #include <Windows.h> #include <iostream> LRESULT CALLBACK RegChangeCallback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_DEVICECHANGE) { if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE) { PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; if (pHdr->dbch_devicetype == DBT_DEVTYP_HANDLE) { PDEV_BROADCAST_HANDLE pHandle = (PDEV_BROADCAST_HANDLE)pHdr; if (pHandle->dbch_eventguid == YOUR_EVENT_GUID) { // 注册表发生变化 std::cout << "注册表发生变化" << std::endl; } } } } return DefWindowProc(hwnd, uMsg, wParam, lParam); } int main() { HKEY hKey; LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, KEY_NOTIFY, &hKey); if (result != ERROR_SUCCESS) { std::cerr << "无法打开注册表键" << std::endl; return 1; } HWND hwnd = CreateWindowEx(0, L"STATIC", nullptr, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr, nullptr); result = RegNotifyChangeKeyValue(hKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, hwnd, TRUE); if (result != ERROR_SUCCESS) { std::cerr << "无法注册注册表变化通知" << std::endl; RegCloseKey(hKey); return 1; } MSG msg; while (GetMessage(&msg, nullptr, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } RegCloseKey(hKey); return 0; } ``` 以上代码使用了`RegOpenKeyEx`函数打开注册表键,并使用`RegNotifyChangeKeyValue`函数注册对该键的变化通知。在窗口的回调函数`RegChangeCallback`中,我们可以捕获注册表变化事件,并做相应的处理。 请注意,这段代码使用了Windows API,并结合了消息循环机制。在您自己的C++程序中,您需要根据具体的需求和情况,修改代码中的`YOUR_EVENT_GUID`为您关注的注册表变化事件的GUID,并根据实际情况进行相应的处理。 运行以上代码后,程序开始监测注册表变化,并在'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall'路径下的注册表发生变化时打印出相应的提示信息。您可以根据自己的需求对代码进行修改,比如添加具体的注册表路径、筛选条件,或者将事件信息保存到文件或进行其他处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值