Ejemplo n.º 1
0
        /// <summary>
        /// Performs tasks associated with listening ETW events on Windows.
        /// </summary>
        /// <param name="runner">Operation to be profiled/traced.</param>
        /// <returns>The return value of the method that the runner delegate encapsulates.</returns>
        public TResult Record(Func <TResult> runner)
        {
            if (runner == null)
            {
                throw new ArgumentNullException(nameof(runner));
            }

            var fi             = new FileInfo(UserSessionData.FileName);
            var kernelFileName = Path.Combine($"{fi.DirectoryName}", $"{Path.GetFileNameWithoutExtension(fi.Name)}.kernel.etl");
            var kernelProvider = KernelProviders.Aggregate(KernelProvider.Default,
                                                           (current, item) => new KernelProvider
            {
                Flags        = current.Flags | item.Flags,
                StackCapture = current.StackCapture | item.StackCapture,
            });
            var needKernelSession = Helper.NeedSeparateKernelSession(kernelProvider);

            if (needKernelSession && !Helper.CanEnableKernelProvider)
            {
                const string message = "The application is required to run as Administrator in order to capture kernel data.";
                WriteErrorLine(message);
                throw new UnauthorizedAccessException(message);
            }

            TResult result;

            WriteDebugLine("ETW capture start.");
            using (var kernelSession = needKernelSession ? Helper.MakeKernelSession(kernelFileName, UserSessionData.BufferSizeMB) : null)
            {
                kernelSession?.EnableKernelProvider(kernelProvider.Flags, kernelProvider.StackCapture);

                using (var userSession = new Session(UserSessionData))
                {
                    UserProviders.ForEach(provider =>
                    {
                        userSession.EnableProvider(provider.Guid, provider.Level, provider.Keywords, provider.Options);
                    });

                    result = runner();
                }
            }
            WriteDebugLine("ETW capture stop.");

            WriteDebugLine("ETW merge start.");
            TraceEventSession.MergeInPlace(UserSessionData.FileName, Console.Out);
            WriteDebugLine("ETW merge stop.");

            return(result);
        }