Ross Holder

At the moment I've got an instrumented application that uses a simple data class derived from "BaseEvent" to output tracing. Trouble is it only works on a single machine. I'd like to create a remote listener (operating on a different machine) so I can have multiple instrumented clients reporting their events to one place.

The trouble I'm having has to do with BaseEvent.Fire(). Currently to transmit data to the listener, I populate data in my simple data class and just call the Fire() method. This approach doesn't seem to work when I've got the listener operating on a different machine.

Can anyone suggest an approach that would let me achieve my stated goal Have hunted up and down the web and found nothing on the subject of using BaseEvent with the "remote computer" scenario.

Gratefully,

RH




Re: Visual C# General Centralized WMI Listener: Approach Wanted

OmegaMan

Maybe think out of the box. Since a listener is local, create a web service which can capture the events locally to that box. Have your application call the webservice and retrieve the latest events on a timed basis.

Otherwise try posting this question to the ASP.Net forums for a possible different scenario on the WMI events...






Re: Visual C# General Centralized WMI Listener: Approach Wanted

Ross Holder

Ya know....this problem was actually really easy to solve - and I'm posting back to the group in case anyone ever runs into this same kind of trouble with WMI. Also because OmegaMan was right - I just needed to "think out of the box".

Part of the problem was the documentation on WMI and .NET is, in some places, a little tough to grasp. (Or maybe I'm slow...but that's how I find it at times.) It was explicitly stated anywhere that one isn't pushing trace data from clients to the listener (or server) - rather the listener pulls the trace data from clients. As such, in this case, the listener needs to be told what machines to listen to.

Once I had this understanding (which only occurred as a thought during my troubleshooting process instead of reading it anywhere) writing the code was fairly simple (note that the WMI node CRAF is something I've created):

16 WqlEventQuery query = new WqlEventQuery("select * from TraceEvent");

17 ManagementScope scope = null;

18 BackgroundWorker bw = null;

19

20 try

21 {

22 //when no arguments are specified, revert to single-instance, local listener

23 if (args.Length > 0)

24 {

25 //read monitoring scope(s) from command line

26 scope = new ManagementScope("\\\\" + (string)args[1] + "\\Root\\CRAF");

27 ConnectionOptions connOps = new ConnectionOptions();

28

29 try

30 {

31 //TODO: consider creating defaults for following values using WindowsPrincipal objects

32 connOps.Username = (string)args[0];

33 Console.Out.WriteLine("Enter password:");

34 connOps.Password = ReadPassword();

35 Console.Out.WriteLine("\n\r");

36 if (args.Length < 3) { connOps.Authority = "ntlmdomain:" + (string)args[1]; }

37 else { connOps.Authority = "ntlmdomain:" + (string)args[2]; }

38 }

39 catch (IndexOutOfRangeException indexEx)

40 {

41 Console.Out.WriteLine("OUT OF RANGE ERROR: A username (without domain) should likely be provided as a command line argument!");

42 }

43

44 scope.Options = connOps;

45 }

46 else

47 {

48 scope = new ManagementScope("root\\CRAF");

49 }

50

51 scope.Connect();

52

53

54 ManagementEventWatcher watcher = new ManagementEventWatcher(scope, query);

55 watcher.Start();



The above code is a listener created out of a Console application. The command line takes between 0 and 3 arguments:

TraceListener.exe [username machinename [domain]]

The arguments take the following effects:
  • with 0 arguments, TraceListener loads to a local configuraiton; no username or password info is necessary,
  • with 2 arguments, a username and machinename, TraceListener is configured to listen to events from machinename, using the credentials of the username provided. Additional logic prompts for a password and events are returned, using the crednetials of the user specified, and
  • with an optional 3rd argument - the domain - the username specified is presumed to exist in the subsequently-specified Windows domain.
Although I haven't needed to complete this feature yet, the listener can presumably be configured to "hear" events from multiple machines simultaneously. Instead of using command-line arguemnts to specify machinenames and credentials, an app.config would contain a collection of machines within a given domain to listen to. Then comes the last remaining question; will threading properly handle events

The answer is an emphatic "yes", and this time - the docuemntation does offer an answer. But the approach is a little different; one needs to turn to the ManagementOperationObserver class to take on the job of the ManagementEventWatcher, suggests this MSDN API article.

So these are my findings. As usual, comments and anything else that might help those of us looking to build a multi-threaded, centralized WMI listeenr would be greatly apprecaited.

ROSS
DCX3


http://ross613.spaces.live.com











Re: Visual C# General Centralized WMI Listener: Approach Wanted

OmegaMan

Thanks for the info Ross!