views:

139

answers:

1

Hi,

I am trying to trigger an event every time a registry value is being modified.

import win32api
import win32event
import win32con
import _winreg
key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,'Control Panel\Desktop',0,_winreg.KEY_READ)
sub_key = _winreg.CreateKey(key,'Wallpaper')
evt = win32event.CreateEvent(None,0,0,None)
win32api.RegNotifyChangeKeyValue(sub_key,1,win32api.REG_NOTIFY_CHANGE_ATTRIBUTES,evt,True)
ret_code=win32event.WaitForSingleObject(evt,3000)
if ret_code == win32con.WAIT_OBJECT_0:
    print "CHANGED"
if ret_code == win32con.WAIT_TIMEOUT:
    print "TIMED"

my problem is that this is never triggered , the event always time-out. (the reg key I am trying to follow is the wallpaper)

[

please note I trigger the event by 1) manually changing the registry value in regedit 2) an automated script which run this :

from ctypes import windll

from win32con import *

windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0,"C:\wall.jpg",SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE)

]

Thanks for any help in advance :)

EDIT:: sorry about formatting

A: 

"WallPaper" is a value not a key/subkey. So if you bring up regedit.exe, you'll notice that you've created a new key "HKCU\Control Panel\Desktop\WallPaper" which is distinct from the "WallPaper" value under the "HKCU\Control Panel\Desktop" key.

Here's one way to modify your code to listen for changes:

key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 'Control Panel\Desktop', 0, _winreg.KEY_READ)
evt = win32event.CreateEvent(None, 0, 0, None)
win32api.RegNotifyChangeKeyValue(key, 1, win32api.REG_NOTIFY_CHANGE_LAST_SET, evt, True)

Note that we don't use a WallPaper subkey any more and note that the "notify fitler" has been changed to NOTIFY_CHANGE_LAST_SET; from the docs this will:

Notify the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value.

The rest of your code will work, but you'll need to use the QueryValueEx function before and after to ensure it was the WallPaper value that changed and not some other. (I don't know of a way to listen for specific values.)

ars