Imports System
Imports System.Threading
Imports System.Runtime.InteropServices
Imports Microsoft.Win32
Public Class RegistryNotification
' egl1044
' Constructor
Public Sub New()
End Sub
<Flags()> _
Public Enum RegNotifyFilter
REG_NOTIFY_CHANGE_NAME = 1 'Notify the caller if a subkey is added or deleted.
REG_NOTIFY_CHANGE_LAST_SET = 4 'Notify the caller of changes to a value of the key. This can include adding or deleting a value or changing an existing value.
End Enum
Public Enum RegType
HKEY_LOCAL_MACHINE = &H80000002
HKEY_CLASSES_ROOT = &H80000000
HKEY_CURRENT_USER = &H80000001
HKEY_USERS = &H80000003
End Enum
' Not implemented in this example.
'<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
'Private Structure REG_NOTIFY_INFORMATION
' Dim NextEntryOffset As Integer
' Dim Action As Integer
' Dim RegNameLength As Integer
' Dim RegName As IntPtr
'End Structure
<DllImport("coredll.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function CeFindCloseRegChange(ByVal hChangeHandle As IntPtr) As Integer
End Function
<DllImport("coredll.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function CeFindFirstRegChange(ByVal hKey As IntPtr, ByVal bWatchSubtree As Integer, ByVal dwNotifyFilter As RegNotifyFilter) As IntPtr
End Function
<DllImport("coredll.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function CeFindNextRegChange(ByVal hChangeHandle As IntPtr) As Integer
End Function
<DllImport("coredll.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function RegOpenKeyEx(ByVal hKey As RegType, ByVal lpSubKey As String, ByVal ulOptions As Integer, ByVal samDesired As Integer, ByRef phkResult As IntPtr) As Integer
End Function
<DllImport("coredll.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function RegCloseKey(ByVal hKey As IntPtr) As Integer
End Function
<DllImport("coredll.dll", SetLastError:=True)> _
Private Shared Function WaitForSingleObject(ByVal handle As IntPtr, ByVal ms As Integer) As Integer
End Function
Private hKey As IntPtr = IntPtr.Zero '// registry handle
Private hChangeHandle As IntPtr = IntPtr.Zero '// registry notification handle
Private NotifyThread As Thread = Nothing
Private bCancel As Boolean = False
Public Sub StartRegistryWatcher()
' Watch for notifications on a seperate thread.
bCancel = False
NotifyThread = New Thread(AddressOf RegistryNotificationThread)
NotifyThread.IsBackground = True
NotifyThread.Start()
End Sub
Public Sub StopRegistryWatcher()
' Cancel notifications on the seperate thread.
bCancel = True
CeFindCloseRegChange(hChangeHandle)
End Sub
' <(THREAD)>
Private Sub RegistryNotificationThread()
' Run change notifications on new thread.
RegisterRegistryChange(RegType.HKEY_LOCAL_MACHINE, "Software\fabrikan", 0)
End Sub
Private Sub RegisterRegistryChange(ByVal rootKey As RegType, ByVal keyName As String, ByVal watchSubTree As Integer)
' Detects registry notifications.
If RegOpenKeyEx(rootKey, keyName, 0, 0, hKey) <> 0 Then
MsgBox("RegOpenKeyEx failed.")
Return
End If
' TODO:// Change filter settings here
hChangeHandle = CeFindFirstRegChange(hKey, watchSubTree, RegNotifyFilter.REG_NOTIFY_CHANGE_LAST_SET)
If hChangeHandle.ToInt32 = -1 Then
MsgBox("CeFindFirstRegChange failed")
RegCloseKey(hKey)
Return
End If
Do While bCancel <> True
WaitForSingleObject(hChangeHandle, Timeout.Infinite)
MsgBox("Change Detected!")
CeFindNextRegChange(hChangeHandle)
Thread.Sleep(0)
Loop
' TODO://
CeFindCloseRegChange(hChangeHandle)
RegCloseKey(hKey)
End Sub
Public Sub DebugCreateRegistryEntry()
' Creates the specified key in the registry for debugging.
Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey("Software", True)
rk.CreateSubKey("fabrikan")
rk.Close()
End Sub
Public Sub DebugChangeRegistryValue()
' Simulate a change in the registry for debugging.
Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey("Software\fabrikan", True)
rk.SetValue("fabrikans", TimeOfDay.Second.ToString, RegistryValueKind.String)
rk.Close()
End Sub
End Class
|