 |
|
 |
I have this silly idea..
Can we get the keys subkeys and the values in any way?
If we can, we can store them in a struct (with fields: name,type,value,solitary hash code) and order it by the field solitary hashcode (which field will be a special solitary number that would generate when the key or value is going to store in the struct through an MD5 or something like algorithm)
then we use the function RegNotifyChangeKeyValue[^] which gives us the key that is modified and not the type and the value). Then we can take in the same struct but in another instance the subkeys and the values of the modified keys and compare them with the first struct (with that we have the changed keys and the values) after comparing the hashcodes of the 2 structs. With that we can find the type that is changed and the value)
is this possible? sounds tricky.
thanks
Alex
|
|
|
|
 |
|
 |
Of course, that's possible.
Regards
Thomas
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
 |
|
 |
Hi,
I'm having problems using the class in a Windows Service. On changing the monitored registry I get the error:
"Object reference not set to an instance of an object.."
The handled 'crash' is in the protected virtual void OnRegChanged() function in the RegistryMonitor class, when setting the handler constructor (Ln99)
The change is clearly caught, but I don't seem to get the signal, any thoughts?
The implementation is simple:
string keyName = string.Format("{0}\\{1}", Registry.LocalMachine.Name, registryPath);
monitor = new RegistryMonitor(keyName);
monitor.RegChanged += new EventHandler(OnRegChanged);
monitor.Error += new System.IO.ErrorEventHandler(OnError);
monitor.Start();
...
private void OnRegChanged(object sender, EventArgs e)...
|
|
|
|
 |
|
 |
Cannot download the attached files.
Are they missing?
Thanks
|
|
|
|
 |
|
 |
I can download both files without a problem. Maybe it was a temporary glitch. Please try again.
Regards
Thomas
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
 |
|
 |
First off - nice article. Very helpful
It looks like there's a thread problem here, though. If I call Start(), then immediately modify the registry programmatically, then the ThreadLoop() call may not have reached RegNotifyChangeKeyValue(), so the change will go unnoticed.
This can be partially fixed by at least waiting in Start() until that call is reached (although that's not a perfect solution).
Also, if a registry change is picked up, then it's possible that another change could occur between OnRegChanged() and the next RegNotifyChangeKeyValue() call, which would also fall through the cracks.
Finally, if the terminate event is signalled, then OnRegChanged() will get called - the code doesn't differentiate between termination or notification.
Is there no alternative method of monitoring the registry, that could be done with, say, callbacks, rather than signalling?
Edit: Ha. My bad - I just checked: RegNotifyChangeKeyValue() will pick up on changes between calls, so my second point is nonsense.
-- modified at 6:52 Monday 20th August, 2007
|
|
|
|
 |
|
 |
Hi
would it be possible to use in .net 2005?
i try, but could not compiled
|
|
|
|
 |
|
 |
I'm using VB 2005 and facing a similar problem here. Here's what my code looks like.
Imports RegistryUtils
Private Sub TestReg_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim objRegMon As New RegistryMonitor(RegistryHive.LocalMachine, "System\CurrentControlSet\Services\USBSTOR")
objRegMon.RegChanged += New EventHandler(OnRegChanged)
objRegMon.Start()
End Sub
I tried to use Intellisense to type objRegMon.RegChanged, but when I hit "." (dot) after objRegMon, I can't find the RegChanged event. I checked the RegistryUtils source code at the RegChanged event, it already stated as Public. What did I do wrong with my code? Or is it just an incompatibility with VS 2005?
|
|
|
|
 |
|
 |
Hi
would it be possible to monitor changes precisely : i mean, knowing what exactly changed ?
|
|
|
|
 |
|
 |
No, you can´t. You can only monitor keys (and subkeys optionally), but not the contained values.
Regards
Thomas
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
 |
|
 |
I'm just wanting to clarify with your response. So there is no way to tell the name of the key that was modified?
jgehman
Software Engineer
|
|
|
|
 |
|
 |
Exactly. My code can't do more than what RegNotifyChangeKeyValue provides.
Regards
Thomas
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
 |
|
 |
Suggested answer for the question: If you organize you data items in multiple sub-keys, you can monitor the sub keys and tell what key has changed from the event.
Codemania
|
|
|
|
 |
|
 |
I would need to know which process caused the registry change notification. Is there any way to obtain this ?
|
|
|
|
 |
|
 |
drinkwater wrote: Is there any way to obtain this ?
No. And you would already know if you would have read the other comments
Regards
Thomas
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
 |
|
 |
You would have to search for this key in the 'handles' of all processes running currently....
|
|
|
|
 |
|
 |
However, the process may already have closed the handle.
Regards
Thomas
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
modified on Monday, August 10, 2009 4:47 AM
|
|
|
|
 |
|
 |
yes thats right ...but its as close as you can get to address the problem, right?..
if you were to monitor the whole thing (i mean all the processes)continously, i think you can catch the culprit...
regards
vivek
|
|
|
|
 |
|
 |
How can I monitor Registry for a special process?
for example, I'm insralling yahoo messenger on my pc, I want to know what changed yahoo messenger has made on my registery ~(*|*)~
where life had no value death sometimes had its price
thats why the bounty killers appeared
|
|
|
|
 |
|
 |
I recommend to use RegMon.
Regards
Thomas
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
 |
|
 |
Thomas,
First of all, thx for this code.
With Visual Studio 2005 there's a warning with RegNotifyChangeKeyValue, where the hEvent parameter needs to be declared as a SafeWaitHandle, instead of the IntPtr. Given that the code is for .NET 1.1 and 2.0, I understand your motivation to keep it "as is". (First post, so I apologize for the code not aligning properly).
My proposal is the following:
- Add a property SynchronizingObject of type ISynchronizeInvoke that allows the class to post on the same thread as the calling object (e.g., for WinForms)
- Update the code for Visual Studio 2005 using safe handles (this would need a new type to wrap the registry handles, similar to the internal SafeRegistryHandle, and redeclaration of RegNotifyChangeKeyValue, as noted above, and RegOpenKeyEx to use the SafeRegistryHandle.
I have a version that implements the SynchronizingObject property (only by checking the InvokeRequired and then calling Invoke on the form. Still have to work on the (Begin/End)Invoke when InvokeRequired is false. The Invoke part works well and calls the event on the creator's thread.
private ISynchronizeInvoke _synchronizer = null;
public System.ComponentModel.ISynchronizeInvoke SynchronizingObject
{
get { return _synchronizer; }
set { _synchronizer = value; }
}
protected virtual void OnRegChanged()
{
EventHandler handler = RegChanged;
if (handler != null)
if (_synchronizer != null)
{ // Marshal event through the synchronizing object
if (_synchronizer.InvokeRequired)
{
_synchronizer.Invoke(handler.GetInvocationList()[0], null);
}
else
{ // [TODO] Use (Begin/End)Invoke
handler(this, null);
}
}
else
{ // Fire event on this object's thread.
handler(this, null);
}
}
I'm also working on a SafeRegistryHandle, but still need to make sure it works in all situations. Here's a partial class (untested)
class SafeRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid
{
#region P/Invoke
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegCloseKey(IntPtr hKey);
#endregion
// Create a SafeRegistryHandle, informing the base class that this
// SafeRegistryHandle instance "owns" the handle, and therefore
// SafeHandle should call our ReleaseHandle method when the SafeRegistryHandle
// is no longer in use.
private SafeRegistryHandle() : base(true)
{
}
protected override bool ReleaseHandle()
{
return RegCloseKey(handle) != 0 ? false : true;
}
}
Regards,
Javier
We must become the change we want to see.
--Gandhi
|
|
|
|
 |
|
 |
Javier, thanks for your valuable feedback. I'll have a closer look at it in a few days.
Regards
Thomas
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
 |
|
 |
Thomas,
I am running multiple instances of RegistryMonitor to watch different keys in a registry. However if there is any change in any of the key, I need to stop the entire instances and then create and start multiple instances again.
But when I call Stop() for each instances, it executes for the first instance and then on second instance,it jumps out after thread.Join() and doesnt go through rest of the code.
Can you suggest some solution? I am using Visual Studio 2005
Thanks
Sanzay
|
|
|
|
 |
|
 |
Hi Sanzay,
I never tried to run multiple instances of RegistryMonitor. I'll investigate this issue.
Regards
Thomas
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
 |
|
 |
Thomas,
Thanks for the response. Here is a description to let you have clear idea of my problem.
Since it is not possible to actually find out which particular subkey has been changed while watching the key, so for my purpose, I created the multiple instances of RegistryMonotor, one for each subkey that I need to monitor.
And once there is any changes in any of the subkeys that is being watched, then I need to stop all the registry monitors and restart again.
So my StartRegistryMonitor() and StopRegistryMonitor() function looks something like
//Note:currentListArray is ArrayList that contains the subkey path for all subkey that I need to monitor
// And registryMonitor is defined as private RegistryMonitor[] registryMonitor in class ;
private void StartRegistryMonitor()
{
this.registryMonitor = new RegistryMonitor[this.currentListArray.Count];
foreach (object obj in this.currentListArray)
{
int index = this.currentSignListArray.IndexOf(obj);
this.registryMonitor[index] = new RegistryMonitor(obj.ToString());
this.registryMonitor[index].RegChanged += new EventHandler(OnRegChanged);
this.registryMonitor[index].Error += new EventHandler(OnError);
this.registryMonitor[index].Start();
}
}
private void StopRegistryMonitor()
{
if (this.registryMonitor != null)
{
for (int i = 0; i < this.registryMonitor.Length; i++)
{
if (this.registryMonitor[i] != null)
{
this.registryMonitor[i].Stop();
this.registryMonitor[i].RegChanged -= new EventHandler(OnRegChanged);
this.registryMonitor[i].Error -= new EventHandler(OnError);
this.registryMonitor[i] = null;
}
}
}
}
For the first instance, when i equals 0, it goes through and stops the registry watcher for the first instance. But when i equals 1, then this.registryMonitor[1].Stop() doesnt successfully execute. Once it reaches to thread.Join() in Stop() function in RegistryMonitor.cs, it doesnt successfully come out of it and stuck over there.
And hence neither the other instances of RegistryMonitor stops nor other codes following in a program
I would appreciate any help and suggestion.
Thanks,
Sanzay
|
|
|
|
 |