/// <summary>
        /// Open an existing Windows Event Tracing Session, with name 'sessionName'.
        ///
        /// If you are opening a new session use TraceEventSession(string, string).
        ///
        /// To support the illusion that you can have a session with both kernel and user events,
        /// TraceEventSession might start up both a kernel and a user session.   When you want to 'attach'
        /// to such a combined session, the constructor needs to know if you want to control the kernel
        /// session or not.  If attachKernelSession is true, then it opens both sessions (and thus 'Close'
        /// will operation on both sessions.
        /// </summary>
        public TraceEventSession(string sessionName, bool attachKernelSession)
        {
            Init(sessionName);
            int hr = TraceEventNativeMethods.ControlTrace(0UL, sessionName, ToUnmanagedBuffer(properties, null), TraceEventNativeMethods.EVENT_TRACE_CONTROL_QUERY);

            Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(hr));
            isActive   = true;
            properties = (TraceEventNativeMethods.EVENT_TRACE_PROPERTIES)Marshal.PtrToStructure(unmanagedPropertiesBuffer, typeof(TraceEventNativeMethods.EVENT_TRACE_PROPERTIES));
            if (properties.LogFileNameOffset != 0)
            {
                fileName = Marshal.PtrToStringUni((IntPtr)(unmanagedPropertiesBuffer.ToInt64() + properties.LogFileNameOffset));
            }

            if (attachKernelSession)
            {
                bool success = false;
                try
                {
                    kernelSession = new TraceEventSession(KernelTraceEventParser.KernelSessionName);
                    success       = true;
                }
                finally
                {
                    if (!success)
                    {
                        Stop();
                    }
                }
            }
        }
        /// <summary>
        /// Once started, event sessions will persist even after the process that created them dies. They are
        /// only stoped by this explicit Stop() API.  If you used both kernel and user events, consider
        /// using the code:StopUserAndKernelSession API instead.
        /// </summary>
        public void Stop()
        {
            if (stopped)
            {
                return;
            }
            stopped = true;
            int hr = TraceEventNativeMethods.ControlTrace(0UL, sessionName,
                                                          ToUnmanagedBuffer(properties, null), TraceEventNativeMethods.EVENT_TRACE_CONTROL_STOP);


            if (hr != 4201)     // Instance name not found.  This means we did not start
            {
                Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(hr));
            }

            if (kernelSession != null)
            {
                kernelSession.Stop();
                kernelSession = null;
            }
        }