如何使用 Python 监听 Windows 注册表变化

101 阅读2分钟

当某些程序启动或运行时,它们可能会修改 Windows 注册表中的某些键值,从而导致系统出现问题或不稳定。需要一种方法来监控注册表的变化,并当监听到注册表被修改时执行一些自动操作,以保证注册表的正确性。

huake2_00020_.png 2. 解决方案

可以使用 Python 的 win32api 和 win32con 模块来监听 Windows 注册表的变化。具体步骤如下:

  1. 导入必要的模块:
import win32api
import win32con
  1. 定义要监听的注册表项和键值:
hiveToWatch = win32con.HKEY_CURRENT_USER
keyToWatch = r'Software\CompanyName\ProgramName'
values = {(hiveToWatch, keyToWatch, 'KeyName'): (win32con.REG_DWORD, 1)}
  1. 打开要监听的注册表项并设置监听标志:
handleWithSetRights = win32api.RegOpenKeyEx(hiveToWatch, keyToWatch, 0, win32con.KEY_SET_VALUE)
win32api.RegNotifyChangeKeyValue(handleWithSetRights, False, win32api.REG_NOTIFY_CHANGE_LAST_SET, None, False)
win32api.RegCloseKey(handleWithSetRights)
  1. 进入一个无限循环,不断地检查注册表项是否发生变化:
while True:
    # 重新打开要监听的注册表项
    handleToBeWatched = win32api.RegOpenKeyEx(hiveToWatch, keyToWatch, 0, win32con.KEY_NOTIFY)
    # 检查注册表项是否发生变化
    if win32api.RegQueryValueEx(handleToBeWatched, 'KeyName') != (win32con.REG_DWORD, 1):
        # 注册表项发生变化,执行自动操作
        print('Registry key changed! Performing automatic actions...')
    # 关闭注册表项句柄
    win32api.RegCloseKey(handleToBeWatched)

当监听到注册表被修改时,可以执行一些自动操作,比如:

  • 重启程序
  • 发送电子邮件通知
  • 备份注册表

代码示例:

import win32api
import win32con
import logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s', filename='watchRegistry.log')
log = logging.getLogger()

hiveToWatch = win32con.HKEY_CURRENT_USER
keyToWatch = r'Software\Microsoft\Calc'

values = {(hiveToWatch, keyToWatch, 'DateTime'): (win32con.REG_DWORD, 1),
          (hiveToWatch, keyToWatch, 'Templates'): (win32con.REG_DWORD, 0),
          (hiveToWatch, keyToWatch, 'UnitConv'): (win32con.REG_DWORD, 0)}

while True:

    for (hive, key, valueName), (valueType, value) in values.items():
        handleWithSetRights = win32api.RegOpenKeyEx(hive, key, 0, win32con.KEY_SET_VALUE)
        log.info(r'Setting %s%s%s = %s' % (hive, key, valueName, value))
        win32api.RegSetValueEx(handleWithSetRights, valueName, 0, valueType, value)
        win32api.RegCloseKey(handleWithSetRights)

    # Open and close the handle here as otherwise the set operation above will trigger a further round
    handleToBeWatched = win32api.RegOpenKeyEx(hiveToWatch, keyToWatch, 0, win32con.KEY_NOTIFY)
    win32api.RegNotifyChangeKeyValue(handleToBeWatched, False, win32api.REG_NOTIFY_CHANGE_LAST_SET, None, False)
    win32api.RegCloseKey(handleToBeWatched)

这段代码会监视 HKEY_CURRENT_USER\Software\Microsoft\Calc 注册表项下的 DateTimeTemplatesUnitConv 键值的变化,并在这些键值发生变化时将它们重置为指定的默认值。