views:

39

answers:

2

I'm getting this error:

Unhandled Exception: System.Runtime.InteropServices.COMException (0x80042001): Exception from HRESULT: 0x80042001 at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo) at System.Management.ManagementEventWatcher.Start() at MyNamespace.Program.Main(String[] args) in {somedir}\Program.cs:line 16

And here's my C# console app that I'm using to watch the registry:

using System;
using System.Management;

namespace MyNamespace
{
    class Program
    {
        static void Main(string[] args)
        {

        var watcher = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM RegistryTreeChangeEvent"));
        var handler = new MyHandler();
        watcher.EventArrived += handler.Arrived;

        //Start watching for events
        watcher.Start();

        while (handler.EventHasntFiredYet)
        {
            // Nothing.
        }

        //Stop watching
        watcher.Stop();
    }

    public class MyHandler
    {
        public bool EventHasntFiredYet;

        public MyHandler()
        {
            EventHasntFiredYet = true;
        }

        public void Arrived(object sender, EventArrivedEventArgs e)
        {
            var propertyDataCollection = e.NewEvent.Properties;
            foreach (var p in propertyDataCollection)
            {
                Console.WriteLine("{0} -- {1}",p.Name,p.Value);
            }
            EventHasntFiredYet = false;
        }
    }
}

}

I'm trying to simply watch the registry for changes. Does anyone have any suggestions as to why this is failing?

+1  A: 

As Hans has told you are receiving the error because you haven't specified where clause. According to Creating a Proper WHERE Clause for the Registry Provider you must specify where clause otherwise you will receive WBEM_E_TOO_BROAD error.

To simplify your code and not to reinvent the wheel you can use the following library: Asynchronous Registry Notification Using Strongly-typed WMI Classes in .NET

Giorgi
+1  A: 

It is an internal WMI error, WBEMESS_E_REGISTRATION_TOO_BROAD, "The provider registration overlaps with the system event domain."

That's about a good an error message as you'd ever get out of COM. Striking how much better the .NET exception messages are. Anyhoo, I'm fairly sure that what it means is "you are asking for WAY too many events". You'll have to be more selective in your query, use the WHERE clause. Like:

SELECT * FROM RegistryTreeChangeEvent
WHERE Hive='HKEY_LOCAL_MACHINE' AND 'RootPath='SOFTWARE\Microsoft'


Prompted by Giorgi, I found the MSDN page that documents the problem:

[snip]
The following is an example of an incorrect registration.

SELECT * FROM RegistryTreeChangeEvent WHERE hive = hkey_local_machine" OR rootpath ="software"

Because there is no way to evaluate the possible values for each of the properties, WMI rejects with the error WBEM_E_TOO_BROAD any query that either does not have a WHERE clause or if the WHERE clause is too broad to be of any use.
[snip]

Hans Passant
That's interesting. I wonder why this answer was voted down.
Sean Ochoa
Revenge downvote.
Hans Passant
@Hans, Actually the documentation does state that you will get this error without where clause.
Giorgi
@Giorgi: thanks! Not easy to find.
Hans Passant
@Hans: It's in the codeproject article I linked to.
Giorgi