public static void Run()

in Microsoft.Diagnostics.Tracing/TraceEvent/TraceEvent/30_MonitorLoads.cs [44:135]


        public static void Run()
        {
            var monitoringTimeSec = 10;

            Out.WriteLine("******************** ModuleLoadMonitor DEMO ********************");
            Out.WriteLine("Monitoring DLL Loads and Process Starts/Stops system wide");
            Out.WriteLine("The monitor will run for a maximum of {0} seconds", monitoringTimeSec);
            Out.WriteLine("Press Ctrl-C to stop monitoring early.");
            Out.WriteLine();
            Out.WriteLine("Start a program to see some events!");
            Out.WriteLine();
            if (TraceEventSession.IsElevated() != true)
            {
                Out.WriteLine("Must be elevated (Admin) to run this program.");
                Debugger.Break();
                return;
            }

            // Start the session as a real time monitoring session,  
            // Before windows 8, there is a restriction that if you wanted kernel events you must name your session 
            // 'NT Kernel Logger' (the value of KernelSessionName) and there can only be one such session and no
            // other ETW providers can be enabled for that session (thus you need two sessions if you want both
            // kernel and non-kernel events (fixed in Win 8).  We want this to work on Win 7 so we live with those
            // restrictions.   
            using (TraceEventSession session = new TraceEventSession(KernelTraceEventParser.KernelSessionName))
            {
                /* BY DEFAULT ETW SESSIONS SURVIVE THE DEATH OF THE PROCESS THAT CREATES THEM! */
                // Unlike most other resources on the system, ETW session live beyond the lifetime of the 
                // process that created them.   This is very useful in some scenarios, but also creates the 
                // very real possibility of leaving 'orphan' sessions running.  
                //
                // To help avoid this by default TraceEventSession sets 'StopOnDispose' so that it will stop
                // the ETW session if the TraceEventSession dies.   Thus executions that 'clean up' the TraceEventSession
                // will clean up the ETW session.   This covers many cases (including throwing exceptions)
                //  
                // However if the process is killed manually (including control C) this cleanup will not happen.  
                // Thus best practices include
                //
                //     * Add a Control C handler that calls session.Dispose() so it gets cleaned up in this common case
                //     * use the same session name run-to-run so you don't create many orphans. 
                //
                // By default TraceEventSessions are in 'create' mode where it assumes you want to create a new session.
                // In this mode if a session already exists, it is stopped and the new one is created.   
                // 
                // Here we install the Control C handler.   
                Console.CancelKeyPress += new ConsoleCancelEventHandler((object sender, ConsoleCancelEventArgs cancelArgs) =>
                {
                    Out.WriteLine("Control C pressed");     // Note that if you hit Ctrl-C twice rapidly you may be called concurrently.  
                    session.Dispose();                          // Note that this causes Process() to return.  
                    cancelArgs.Cancel = true;                   // This says don't abort, since Process() will return we can terminate nicely.   
                });

                // Enable the Kernel events that we want.   At this point data is being collected (but being buffered since we are not reading it)
                // See KernelTraceEventParser.Keywords for what else can be turned on and KernelTraceEventParser for a description
                // of the events that you get when you turn on the various kernel keywords.   Many kernel events will also log a stack
                // when they fire see EnableKernelProvider for more on that.  
                session.EnableKernelProvider(KernelTraceEventParser.Keywords.ImageLoad | KernelTraceEventParser.Keywords.Process);

                // .Source will auto-create a TraceEventSource reading the data from the session
                // .Kernel will auto-create a KernelTraceEventParser getting its events from the source
                // .ImageLoad is an event that you can subscribe to that will be called back when Image load events happen (complete with parsed event)
                session.Source.Kernel.ImageLoad += delegate(ImageLoadTraceData data)
                {
                    Out.WriteLine("Process {0,16} At 0x{1,8:x} Loaded {2}", data.ProcessName, data.ImageBase, data.FileName);
                };
                //  Subscribe to more events (process start) 
                session.Source.Kernel.ProcessStart += delegate(ProcessTraceData data)
                {
                    Out.WriteLine("Process Started {0,6} Parent {1,6} Name {2,8} Cmd: {3}",
                        data.ProcessID, data.ParentID, data.ProcessName, data.CommandLine);
                };
                //  Subscribe to more events (process end)
                session.Source.Kernel.ProcessStop += delegate(ProcessTraceData data)
                {
                    Out.WriteLine("Process Ending {0,6} ", data.ProcessID);
                };

                // Set up a timer to stop processing after monitoringTimeSec
                var timer = new Timer(delegate(object state)
                {
                    Out.WriteLine("Stopped after {0} sec", monitoringTimeSec);
                    session.Source.StopProcessing();
                }, null, monitoringTimeSec * 1000, Timeout.Infinite);

                // Start listening for events, will end if session.Source.StopProcessing() is called or session.Dispose() is called.  
                // Here we never do either of these and thus will only stop when Ctrl-C is hit (but it will clean up because of 
                // our control C handler). 
                session.Source.Process();
                timer.Dispose();    // Done with the timer.  
            }
            Out.WriteLine("Stopping monitor");
        }