P/Invoke.注册表监测
搞c#3周了,还是用起来觉得不顺。自己写不出来新东西,在codeproject上找了个监测注册表的,结果在.net 2.0上跑不起来,结果问问作者,说是2.0和1.0中的有点出入,结果当时没有来得及看到,导致我自己完全pinvoke了一个类。所以贴出来让大家批判一下,老风格:贴代码,很简单,不做说明了。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;

namespace hhRegMonitor

{
//监测的类型
public class RegChangeNotifyFilter
{
public static long Key
{
get
{ return 0x00000001L; } // REG_NOTIFY_CHANGE_NAME = 1,
}
public static long Attribute
{
get
{ return 0x00000002L; } // REG_NOTIFY_CHANGE_ATTRIBUTES = 2,
}
public static long Value
{
get
{ return 0x00000004L; }// REG_NOTIFY_CHANGE_LAST_SET = 4,
}
public static long Security
{
get
{ return 0x00000008L; } //REG_NOTIFY_CHANGE_SECURITY = 8,
}
}
//监测的根
public class RegRootKey
{
public static long HKEY_LOCAL_MACHINE
{
get
{ return 0x80000002L;}
}
public static long HKEY_CURRENT_USER
{
get
{ return 0x80000001L; }
}
}
public class RegistryMonitor
{
public RegistryMonitor()
{
}
//输出错误信息
public event System.IO.ErrorEventHandler MonitorError;
//事件发生时需要激发的函数
public event EventHandler RegChanged;
public RegistryMonitor(long pfilter,
long proot, string psubkey)
{
_subkey = psubkey;
_rootkey = proot;
_filter = pfilter;
}
private void WaitForChange()
{
try
{
IntPtr myKey;
unchecked
{
RegOpenKey(new IntPtr((int)_rootkey), _subkey, out myKey);
RegNotifyChangeKeyValue(myKey, true,
(int)_filter, _eventhandle, true);
WaitForSingleObject(_eventhandle, INFINITE);
}
}
catch (Exception e)
{
if (MonitorError != null)
MonitorError(this, new System.IO.ErrorEventArgs(e));
}
}
public bool Monitoring()
{
return _notirythread != null;
}
public void StartMonitor()
{
lock (this)
{
if (_notirythread != null)
{
throw new InvalidOperationException("Monitoring
..");
}
else
{
_notirythread = new Thread(new ThreadStart(ThreadLoop));
_notirythread.IsBackground = true;
_notirythread.Start();
}
}
}
public void StopMonitor()
{
lock (this)
{
_notirythread.Join();
_notirythread = null;
}
}
public long Filter
{
get
{ return _filter; }
set
{
if (_notirythread == null)
{
_filter = value;
}
else
{
throw new InvalidOperationException("Monitoring
..");
}
}
}
public long Root
{
get
{ return _rootkey; }
set
{
if (_notirythread == null)
{
_rootkey = value;
}
else
{
throw new InvalidOperationException("Monitoring
..");
}
}
}
public string SubKey
{
get
{ return _subkey; }
set
{
if (_notirythread == null)
{
_subkey = value;
}
else
{
throw new InvalidOperationException("Monitoring
..");
}
}
}
private void ThreadLoop()
{
try
{
while (_notirythread != null)
{
WaitForChange();
if (RegChanged != null)
RegChanged(this, EventArgs.Empty);
}
}
catch (Exception e)
{
if (MonitorError != null)
MonitorError(this, new System.IO.ErrorEventArgs(e));
_notirythread = null;
}
}
DllImport#region DllImport
[DllImport("kernel32.dll", EntryPoint = "CreateEvent")]
static extern IntPtr CreateEvent(IntPtr eventAttributes,
bool manualReset, bool initialState, String name);
[DllImport("advapi32.dll", EntryPoint = "RegOpenKey")]
static extern IntPtr RegOpenKey(IntPtr key, String subKey,
out IntPtr resultSubKey);
[DllImport("advapi32.dll", EntryPoint = "RegNotifyChangeKeyValue")]
static extern long RegNotifyChangeKeyValue(IntPtr key,
bool watchSubTree, int notifyFilter, IntPtr regEvent, bool
async);
[DllImport("kernel32.dll", EntryPoint = "WaitForSingleObject")]
static extern long WaitForSingleObject(IntPtr handle, int timeOut);
[DllImport("kernel32.dll", EntryPoint = "CloseHandle")]
#endregion

some private members#region some private members
private static extern IntPtr CloseHandle(IntPtr handle);
private IntPtr _eventhandle = CreateEvent((IntPtr)null, false, false, "hhregmonitor");
private long _filter = 0;
private long _rootkey = 0;
private const int INFINITE = -1;
private Thread _notirythread = null;
//要监测的路径
private string _subkey = "";
#endregion
}
}
测试demo
class Program
{
static void Main(string[] args)
{
testmonitor test = new testmonitor();
test.monitorreg();
Console.Read();
}
}
public class testmonitor
{
private RegistryMonitor registryMonitor = null;
public testmonitor()
{
}
public void monitorreg()
{
registryMonitor = new RegistryMonitor(RegChangeNotifyFilter.Key,
RegRootKey.HKEY_LOCAL_MACHINE,
"software");
registryMonitor.RegChanged += new EventHandler(OnRegChanged);
registryMonitor.MonitorError += new System.IO.ErrorEventHandler(OnError);

registryMonitor.StartMonitor();
}
private void OnRegChanged(object sender, EventArgs e)
{
Console.Write("change ");
}
private void OnError(object sender, System.IO.ErrorEventArgs e)
{
Console.Write("Regmonitor Err: " + e.GetException().Message);
}类结构参考 http://www.codeproject.com/csharp/registrymonitor.asp
浙公网安备 33010602011771号