public void Start()

in src/PerfView/CommandProcessor.cs [304:999]


        public void Start(CommandLineArgs parsedArgs)
        {
            LaunchPerfViewElevatedIfNeeded("Start", parsedArgs);

            // Are we on an X86 machine?
            if (Environment.Is64BitOperatingSystem)
            {
                if (!IsKernelStacks64Enabled())
                {
                    var ver = Environment.OSVersion.Version.Major * 10 + Environment.OSVersion.Version.Minor;
                    if (ver <= 61)
                    {
                        LogFile.WriteLine("Warning: This trace is being collected on a X64 machine on a Pre Win8 OS");
                        LogFile.WriteLine("         And paging is allowed in the kernel.  This can cause stack breakage");
                        LogFile.WriteLine("         when samples are taken in the kernel and there is memory pressure.");
                        LogFile.WriteLine("         It is recommended that you disable paging in the kernel to decrease");
                        LogFile.WriteLine("         the number of broken stacks.   To do this run the command:");
                        LogFile.WriteLine("");
                        LogFile.WriteLine("         PerfView EnableKernelStacks ");
                        LogFile.WriteLine("");
                        LogFile.WriteLine("         A reboot will be required for the change to have an effect.");
                        LogFile.WriteLine("");
                    }
                }
            }

            ETWClrProfilerTraceEventParser.Keywords profilerKeywords = 0;
            if (parsedArgs.DotNetCalls)
            {
                profilerKeywords |= ETWClrProfilerTraceEventParser.Keywords.Call;
            }

            if (parsedArgs.DotNetCallsSampled)
            {
                profilerKeywords |= ETWClrProfilerTraceEventParser.Keywords.CallSampled;
            }

            if (parsedArgs.DotNetAlloc)
            {
                profilerKeywords |= ETWClrProfilerTraceEventParser.Keywords.GCAlloc;
            }

            if (parsedArgs.DotNetAllocSampled)
            {
                profilerKeywords |= ETWClrProfilerTraceEventParser.Keywords.GCAllocSampled;
            }

            if (parsedArgs.DisableInlining)
            {
                profilerKeywords |= ETWClrProfilerTraceEventParser.Keywords.DisableInlining;
            }

            if (parsedArgs.RuntimeLoading)
            {
                parsedArgs.ClrEvents |= ClrTraceEventParser.Keywords.CompilationDiagnostic;
                parsedArgs.ClrEvents |= ClrTraceEventParser.Keywords.MethodDiagnostic;
                parsedArgs.ClrEvents |= ClrTraceEventParser.Keywords.TypeDiagnostic;
            }

            if (profilerKeywords != 0)
            {
                InstallETWClrProfiler(LogFile, (int)profilerKeywords);
                LogFile.WriteLine("WARNING: Only processes that start after this point will log object allocation events.");
            }

            if (parsedArgs.DataFile == null)
            {
                parsedArgs.DataFile = "PerfViewData.etl";
            }

            // The DataFile does not have the .zip associated with it (it is implied)
            if (parsedArgs.DataFile.EndsWith(".etl.zip", StringComparison.OrdinalIgnoreCase))
            {
                parsedArgs.DataFile = parsedArgs.DataFile.Substring(0, parsedArgs.DataFile.Length - 4);
            }
            else if(!parsedArgs.DataFile.EndsWith(".etl"))
            {
                parsedArgs.DataFile = parsedArgs.DataFile + ".etl";
            }

            // Don't clobber the results file if we were told not to.  
            if (parsedArgs.CollectMultiple > 1)
            {
                var finalResultFile = parsedArgs.DataFile;
                if (parsedArgs.ShouldZip)
                {
                    finalResultFile = finalResultFile + ".zip";
                }

                finalResultFile = GetNewFile(finalResultFile);
                if (parsedArgs.ShouldZip)
                {
                    finalResultFile = finalResultFile.Substring(0, finalResultFile.Length - 4);
                }

                parsedArgs.DataFile = finalResultFile;
            }

            string zipFileName = Path.ChangeExtension(parsedArgs.DataFile, ".etl.zip");
            string userFileName = Path.ChangeExtension(parsedArgs.DataFile, ".etl");
            string kernelFileName = Path.ChangeExtension(parsedArgs.DataFile, ".kernel.etl");
            string heapFileName = Path.ChangeExtension(parsedArgs.DataFile, ".userheap.etl");
            string rundownFileName = Path.ChangeExtension(parsedArgs.DataFile, ".clrRundown.etl");
            string kernelRundownFileName = Path.ChangeExtension(parsedArgs.DataFile, ".kernelRundown.etl");
            // Ensure that old data is gone
            var fileNames = new string[] { zipFileName, userFileName, kernelFileName, heapFileName, rundownFileName, kernelRundownFileName };
            try
            {
                foreach (var fileName in fileNames)
                {
                    FileUtilities.ForceDelete(fileName);
                }
            }
            catch (IOException)
            {
                LogFile.WriteLine("Files in use, aborting and trying again.");
                Abort(parsedArgs);
                foreach (var fileName in fileNames)
                {
                    FileUtilities.ForceDelete(fileName);
                }
            }
            if (parsedArgs.Wpr)
            {
                // Just creating this directory is enough for the rest to 'just work' 
                var ngenPdbs = parsedArgs.DataFile + ".ngenpdb";
                LogFile.WriteLine("Putting NGEN pdbs into {0}", ngenPdbs);
                Directory.CreateDirectory(ngenPdbs);
            }

            CollectingData = true;
            // Create the sessions

            if (parsedArgs.InMemoryCircularBuffer)
            {
                kernelFileName = null;              // In memory buffers dont have a file name  
            }
            else
            {
                LogFile.WriteLine("[Kernel Log: {0}]", Path.GetFullPath(kernelFileName));
            }

            using (TraceEventSession kernelModeSession = new TraceEventSession(s_KernelessionName, kernelFileName))
            {
                if (parsedArgs.CpuCounters != null)
                {
                    SetCpuCounters(parsedArgs.CpuCounters);
                    parsedArgs.KernelEvents |= KernelTraceEventParser.Keywords.PMCProfile;
                }
                else
                {
                    if ((parsedArgs.KernelEvents & KernelTraceEventParser.Keywords.PMCProfile) != 0)
                    {
                        throw new ApplicationException("The PMCProfile should not be set explicitly.  Simply set the CpuCounters.");
                    }
                }

                LogFile.WriteLine("Kernel keywords enabled: {0}", parsedArgs.KernelEvents);
                if (parsedArgs.KernelEvents != KernelTraceEventParser.Keywords.None)
                {
                    if ((parsedArgs.KernelEvents & (KernelTraceEventParser.Keywords.Process | KernelTraceEventParser.Keywords.ImageLoad)) == 0 &&
                        (parsedArgs.KernelEvents & (KernelTraceEventParser.Keywords.Profile | KernelTraceEventParser.Keywords.ContextSwitch)) != 0)
                    {
                        LogFile.WriteLine("Kernel process and image thread events not present, adding them");
                        parsedArgs.KernelEvents |= (
                            KernelTraceEventParser.Keywords.Process |
                            KernelTraceEventParser.Keywords.ImageLoad |
                            KernelTraceEventParser.Keywords.Thread);
                    }

                    // If these are on, turn on Virtual Allocs as well.  
                    if (parsedArgs.OSHeapProcess != 0 || parsedArgs.OSHeapExe != null || parsedArgs.DotNetAlloc || parsedArgs.DotNetAllocSampled)
                    {
                        parsedArgs.KernelEvents |= KernelTraceEventParser.Keywords.VirtualAlloc;
                    }

                    kernelModeSession.BufferSizeMB = parsedArgs.BufferSizeMB;
                    kernelModeSession.StackCompression = parsedArgs.StackCompression;
                    kernelModeSession.CpuSampleIntervalMSec = parsedArgs.CpuSampleMSec;
                    if (parsedArgs.CircularMB != 0)
                    {
                        kernelModeSession.CircularBufferMB = parsedArgs.CircularMB;
                    }

                    kernelModeSession.EnableKernelProvider(parsedArgs.KernelEvents, parsedArgs.KernelEvents);
                }

                // Turn on the OS Heap stuff if anyone asked for it.  
                TraceEventSession heapSession = null;
                if (parsedArgs.OSHeapProcess != 0 || parsedArgs.OSHeapExe != null)
                {
                    if (parsedArgs.OSHeapProcess != 0 && parsedArgs.OSHeapExe != null)
                    {
                        throw new ApplicationException("OSHeapProcess and OSHeapExe cannot both be specified simultaneously.");
                    }

                    heapSession = new TraceEventSession(s_HeapSessionName, heapFileName);
                    // Default is 256Meg and twice whatever the others are
                    heapSession.BufferSizeMB = Math.Max(256, parsedArgs.BufferSizeMB * 2);

                    if (parsedArgs.CircularMB != 0)
                    {
                        LogFile.WriteLine("[Warning: OS Heap provider does not use Circular buffering.]");
                    }

                    if (parsedArgs.OSHeapProcess != 0)
                    {
                        heapSession.EnableWindowsHeapProvider(parsedArgs.OSHeapProcess);
                        LogFile.WriteLine("[Enabling heap logging for process {0} to : {1}]", parsedArgs.OSHeapProcess, Path.GetFullPath(heapFileName));
                    }
                    else
                    {
                        parsedArgs.OSHeapExe = Path.ChangeExtension(parsedArgs.OSHeapExe, ".exe");
                        heapSession.EnableWindowsHeapProvider(parsedArgs.OSHeapExe);
                        LogFile.WriteLine("[Enabling heap logging for process with EXE {0} to : {1}]", parsedArgs.OSHeapExe, Path.GetFullPath(heapFileName));
                    }
                }

                if (parsedArgs.InMemoryCircularBuffer)
                {
                    userFileName = null;                    // In memory buffers don't have a file name 
                }
                else
                {
                    LogFile.WriteLine("[User mode Log: {0}]", Path.GetFullPath(userFileName));
                }

                using (TraceEventSession userModeSession = new TraceEventSession(s_UserModeSessionName, userFileName))
                {
                    TraceEventProviderOptions options = new TraceEventProviderOptions();
                    if (parsedArgs.FocusProcess != null)
                    {
                        int processId;
                        if (Int32.TryParse(parsedArgs.FocusProcess, out processId))
                        {
                            options.ProcessIDFilter = new List<int>(1) { processId };
                            LogFile.WriteLine("**** /FocusProcess specified LIMITING user mode events to process with ID {0}", processId);
                        }
                        else
                        {
                            if (!parsedArgs.FocusProcess.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
                                LogFile.WriteLine("**** WARNING: process name does not end in .exe, likely you will exclude processes of interest");

                            LogFile.WriteLine("**** /FocusProcess specified LIMITING user mode events to process with name {0}", parsedArgs.FocusProcess);
                            options.ProcessNameFilter = new List<string>(1) { parsedArgs.FocusProcess };
                        }
                    }

                    if (parsedArgs.EnableEventsInContainers)
                    {
                        options.EnableInContainers = true;
                    }
                    if (parsedArgs.EnableSourceContainerTracking)
                    {
                        options.EnableSourceContainerTracking = true;
                    }

                    var stacksEnabled = options.Clone();
                    stacksEnabled.StacksEnabled = true;

                    userModeSession.BufferSizeMB = parsedArgs.BufferSizeMB;
                    // DotNetAlloc needs a large buffer size too.  
                    if (parsedArgs.DotNetAlloc || parsedArgs.DotNetCalls)
                    {
                        userModeSession.BufferSizeMB = Math.Max(512, parsedArgs.BufferSizeMB * 2);
                    }

                    // Note that you don't need the rundown 300Meg if you are V4.0.
                    if (parsedArgs.CircularMB != 0)
                    {
                        // Typically you only need less than 1/5 the space + rundown. However, some scenarios primarily
                        // use the user mode session so we keep it the full size.
                        userModeSession.CircularBufferMB = parsedArgs.CircularMB + 300;
                    }

                    // Turn on PerfViewLogger
                    EnableUserProvider(userModeSession, "PerfViewLogger", PerfViewLogger.Log.Guid,
                        TraceEventLevel.Verbose, ulong.MaxValue, options);

                    Thread.Sleep(100);  // Give it at least some time to start, it is not synchronous. 

                    PerfViewLogger.Log.StartTracing();
                    PerfViewLogger.StartTime = DateTime.UtcNow;

                    PerfViewLogger.Log.SessionParameters(s_KernelessionName, kernelFileName ?? "",
                        kernelModeSession.BufferSizeMB, kernelModeSession.CircularBufferMB);
                    PerfViewLogger.Log.KernelEnableParameters(parsedArgs.KernelEvents, parsedArgs.KernelEvents);
                    PerfViewLogger.Log.SessionParameters(s_UserModeSessionName, userFileName ?? "",
                        userModeSession.BufferSizeMB, userModeSession.CircularBufferMB);

                    // If you turn on allocation sampling, then you also need the types and names and deaths.  
                    if ((parsedArgs.ClrEvents & (ClrTraceEventParser.Keywords.GCSampledObjectAllocationHigh | ClrTraceEventParser.Keywords.GCSampledObjectAllocationLow)) != 0)
                    {
                        parsedArgs.ClrEvents |= ClrTraceEventParser.Keywords.Type | ClrTraceEventParser.Keywords.GCHeapSurvivalAndMovement;
                    }

                    if (parsedArgs.Wpr)
                    {
                        SetWPRProviders(userModeSession, options);
                    }
                    else if (parsedArgs.ClrEvents != ClrTraceEventParser.Keywords.None)
                    {

                        // If we don't change the core set then we should assume the user wants more stuff.  
                        var coreClrEvents = ClrTraceEventParser.Keywords.Default &
                            ~ClrTraceEventParser.Keywords.NGen & ~ClrTraceEventParser.Keywords.SupressNGen;

                        if ((parsedArgs.ClrEvents & coreClrEvents) == coreClrEvents)
                        {
                            LogFile.WriteLine("Turning on more CLR GC, JScript and ASP.NET Events.");

                            // Turn on DotNet Telemetry
                            EnableUserProvider(userModeSession, "DotNet",
                                new Guid("319dc449-ada5-50f7-428e-957db6791668"), TraceEventLevel.Verbose, ulong.MaxValue, stacksEnabled);

                            // Turn on ETW logging about etw logging (so we get lost event info) ... (Really need a separate session to get the lost event Info properly). 
                            EnableUserProvider(userModeSession, "Microsoft-Windows-Kernel-EventTracing",
                                new Guid("B675EC37-BDB6-4648-BC92-F3FDC74D3CA2"), TraceEventLevel.Verbose, 0x70, stacksEnabled);

                            // Turn on File Create (open) logging as it is useful for investigations and lightweight. 
                            // Don't bother if the Kernel FileIOInit events are on because they are strictly better
                            // and you end up with annoying redundancy.  
                            if ((parsedArgs.KernelEvents & KernelTraceEventParser.Keywords.FileIOInit) == 0)
                            {
                                // 0x80 = CREATE_FILE (which is any open, including GetFileAttributes etc.   
                                EnableUserProvider(userModeSession, "Microsoft-Windows-Kernel-File",
                                    new Guid("EDD08927-9CC4-4E65-B970-C2560FB5C289"), TraceEventLevel.Verbose, 0x80, stacksEnabled);
                            }

                            // Turn on the user-mode Process start events.  This allows you to get the stack of create-process calls
                            // 0x10 =  Process  
                            EnableUserProvider(userModeSession, "Microsoft-Windows-Kernel-Process",
                                new Guid("22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716"), TraceEventLevel.Informational, 0x10, stacksEnabled);

                            // Default CLR events also means ASP.NET and private events. 
                            // Turn on ASP.NET at informational by default.
                            EnableUserProvider(userModeSession, "ASP.NET", AspNetTraceEventParser.ProviderGuid,
                                parsedArgs.ClrEventLevel, ulong.MaxValue - 0x2, options); // the - 0x2 will turn off Module level logging, which is very verbose
                            CheckAndWarnAboutAspNet(AspNetTraceEventParser.ProviderGuid);

                            // Turn on the new V4.5.1 ASP.Net  EventSource (TODO Not clear we should do this, and how much to turn on).  
                            // TODO turned on stacks for debugging probably should turn off in the long run.  
                            EnableUserProvider(userModeSession, "*Microsoft-Windows-ASPNET",
                                 new Guid("ee799f41-cfa5-550b-bf2c-344747c1c668"), TraceEventLevel.Informational, ulong.MaxValue, stacksEnabled);

                            // Turn on just minimum (start and stop) for IIS)
                            EnableUserProvider(userModeSession, "Microsoft-Windows-IIS",
                                new Guid("DE4649C9-15E8-4FEA-9D85-1CDDA520C334"), TraceEventLevel.Critical, 0, options);

                            // These let you see IE in and have few events. 
                            EnableUserProvider(userModeSession, "Microsoft-PerfTrack-IEFRAME",
                                new Guid("B2A40F1F-A05A-4DFD-886A-4C4F18C4334C"), TraceEventLevel.Verbose, ulong.MaxValue, options);

                            EnableUserProvider(userModeSession, "Microsoft-PerfTrack-MSHTML",
                                new Guid("FFDB9886-80F3-4540-AA8B-B85192217DDF"), TraceEventLevel.Verbose, ulong.MaxValue, options);

                            // Set you see the URLs that IE is processing. 
                            EnableUserProvider(userModeSession, "Microsoft-Windows-WinINet",
                                new Guid("43D1A55C-76D6-4F7E-995C-64C711E5CAFE"), TraceEventLevel.Verbose, 2, options);

                            // Turn on WCF.  This can be very verbose.  We need to figure out a balance  
                            EnableUserProvider(userModeSession, "Microsoft-Windows-Application Server-Applications",
                                ApplicationServerTraceEventParser.ProviderGuid, TraceEventLevel.Informational, ulong.MaxValue, options);

                            EnableUserProvider(userModeSession, "Microsoft-IE",
                                new Guid("9E3B3947-CA5D-4614-91A2-7B624E0E7244"), TraceEventLevel.Informational, 0x1300, options);

                            EnableUserProvider(userModeSession, "Microsoft-Windows-DNS-Client",
                                new Guid("1C95126E-7EEA-49A9-A3FE-A378B03DDB4D"), TraceEventLevel.Informational, ulong.MaxValue, options);

                            EnableUserProvider(userModeSession, "Microsoft-Windows-DirectComposition",
                                new Guid("C44219D0-F344-11DF-A5E2-B307DFD72085"), TraceEventLevel.Verbose, 0x4, options);

                            EnableUserProvider(userModeSession, "Microsoft-Windows-Immersive-Shell",
                                new Guid("315A8872-923E-4EA2-9889-33CD4754BF64"), TraceEventLevel.Informational, ulong.MaxValue, options);

                            EnableUserProvider(userModeSession, "Microsoft-Windows-XAML",
                                new Guid("531A35AB-63CE-4BCF-AA98-F88C7A89E455"), TraceEventLevel.Informational, ulong.MaxValue, options);

                            // Turn on JScript events too
                            EnableUserProvider(userModeSession, "Microsoft-JScript", JScriptTraceEventParser.ProviderGuid,
                                TraceEventLevel.Verbose, ulong.MaxValue, options);

                            EnableUserProvider(userModeSession, "CLRPrivate", ClrPrivateTraceEventParser.ProviderGuid,
                                TraceEventLevel.Informational,
                                (ulong)(
                                    ClrPrivateTraceEventParser.Keywords.GC |
                                    ClrPrivateTraceEventParser.Keywords.Binding |
                                    ClrPrivateTraceEventParser.Keywords.Fusion |
                                    ClrPrivateTraceEventParser.Keywords.MulticoreJit |   /* only works on verbose */
                                    // ClrPrivateTraceEventParser.Keywords.LoaderHeap |     /* only verbose */
                                    //  ClrPrivateTraceEventParser.Keywords.Startup 
                                    ClrPrivateTraceEventParser.Keywords.Stack
                                ), options);

                            if (parsedArgs.TplEvents != TplEtwProviderTraceEventParser.Keywords.None)
                            {
                                // Used to determine what is going on with tasks.
                                var netTaskStacks = stacksEnabled;
                                if (TraceEventProviderOptions.FilteringSupported)
                                {
                                    // This turns on stacks only for TaskScheduled (7) TaskWaitSend (10) and AwaitTaskContinuationScheduled (12)
                                    netTaskStacks = options.Clone();
                                    netTaskStacks.EventIDStacksToEnable = new List<int>(3) { 7, 10, 12 };
                                }
                                EnableUserProvider(userModeSession, ".NETTasks",
                                    TplEtwProviderTraceEventParser.ProviderGuid, parsedArgs.ClrEventLevel,
                                    (ulong)parsedArgs.TplEvents,
                                    netTaskStacks);
                            }

                            EnableUserProvider(userModeSession, ".NETFramework",
                                FrameworkEventSourceTraceEventParser.ProviderGuid,
                                 parsedArgs.ClrEventLevel,
                                (ulong)(
                                    FrameworkEventSourceTraceEventParser.Keywords.ThreadPool |
                                    FrameworkEventSourceTraceEventParser.Keywords.ThreadTransfer |
                                    FrameworkEventSourceTraceEventParser.Keywords.NetClient),
                                stacksEnabled);

                            // Turn on the Nuget package provider that tracks activity IDs. 
                            EnableUserProvider(userModeSession, "Microsoft.Tasks.Nuget", TraceEventProviders.GetEventSourceGuidFromName("Microsoft.Tasks.Nuget"), TraceEventLevel.Informational, 0x80, options);

                            // Turn on new SQL client logging 
                            EnableUserProvider(userModeSession, "Microsoft-AdoNet-SystemData",
                                TraceEventProviders.GetEventSourceGuidFromName("Microsoft-AdoNet-SystemData"),
                                TraceEventLevel.Informational,
                                1, // This enables just the client events.  
                                stacksEnabled);

                            EnableUserProvider(userModeSession, "ETWCLrProfiler Diagnostics",
                                new Guid(unchecked((int)0x6652970f), unchecked((short)0x1756), unchecked((short)0x5d8d), 0x08, 0x05, 0xe9, 0xaa, 0xd1, 0x52, 0xaa, 0x79),
                                TraceEventLevel.Verbose, ulong.MaxValue, options);

                            // TODO should we have stacks on for everything?
                            var diagSourceOptions = stacksEnabled.Clone();
                            // The removal of IgnoreShortCutKeywords turns on HTTP incoming and SQL events
                            // The spec below turns on outgoing Http requests.  
                            string filterSpec =
                                "HttpHandlerDiagnosticListener/System.Net.Http.Request@Activity2Start:" +
                                "Request.RequestUri" +
                                "\n" +
                                "HttpHandlerDiagnosticListener/System.Net.Http.Response@Activity2Stop:" +
                                "Response.StatusCode";
                            diagSourceOptions.AddArgument("FilterAndPayloadSpecs", filterSpec);
                            const ulong IgnoreShortCutKeywords = 0x0800;    // Turing this OFF enables all the shortcut keywords (ASP.NET and Entity Framework).  
                            EnableUserProvider(userModeSession, "Microsoft-Diagnostics-DiagnosticSource",
                                new Guid("adb401e1-5296-51f8-c125-5fda75826144"),
                                TraceEventLevel.Informational, ulong.MaxValue - IgnoreShortCutKeywords, diagSourceOptions);

                            // This is likely redundant with the diagnosticSource above, but is simpler to parse on the reader side.

                            EnableUserProvider(userModeSession, "Microsoft-AspNetCore-Hosting",
                                new Guid("9e620d2a-55d4-5ade-deb7-c26046d245a8"), TraceEventLevel.Verbose, ulong.MaxValue, options);

                            EnableUserProvider(userModeSession, "Microsoft-ApplicationInsights-Core",
                                new Guid("74af9f20-af6a-5582-9382-f21f674fb271"),
                                TraceEventLevel.Verbose, ulong.MaxValue, stacksEnabled);

                            // Turn on Power stuff
                            EnableUserProvider(userModeSession, "Microsoft-Windows-Kernel-Power",
                                new Guid("331C3B3A-2005-44C2-AC5E-77220C37D6B4"), TraceEventLevel.Informational, 0xFFB, options);
                            EnableUserProvider(userModeSession, "Microsoft-Windows-Kernel-Processor-Power",
                                new Guid("0F67E49F-FE51-4E9F-B490-6F2948CC6027"), TraceEventLevel.Informational, 0xE5D, options);
                            EnableUserProvider(userModeSession, "Microsoft-Windows-PowerCpl",
                                new Guid("B1F90B27-4551-49D6-B2BD-DFC6453762A6"), TraceEventLevel.Informational, ulong.MaxValue, options);
                            EnableUserProvider(userModeSession, "Microsoft-Windows-PowerCfg",
                                 new Guid("9F0C4EA8-EC01-4200-A00D-B9701CBEA5D8"), TraceEventLevel.Informational, ulong.MaxValue, options);

                            // If we have turned on CSwitch and ReadyThread events, go ahead and turn on networking stuff and antimalware too.
                            // It does not increase the volume in a significant way and they can be pretty useful.
                            if ((parsedArgs.KernelEvents & (KernelTraceEventParser.Keywords.Dispatcher | KernelTraceEventParser.Keywords.ContextSwitch))
                                == (KernelTraceEventParser.Keywords.Dispatcher | KernelTraceEventParser.Keywords.ContextSwitch))
                            {
                                EnableUserProvider(userModeSession, MicrosoftAntimalwareEngineTraceEventParser.ProviderName,
                                    MicrosoftAntimalwareEngineTraceEventParser.ProviderGuid,
                                    TraceEventLevel.Verbose, ulong.MaxValue, stacksEnabled);

                                EnableUserProvider(userModeSession, MicrosoftAntimalwareAMFilterTraceEventParser.ProviderName,
                                    MicrosoftAntimalwareAMFilterTraceEventParser.ProviderGuid,
                                    TraceEventLevel.Verbose, ulong.MaxValue, stacksEnabled);

                                EnableUserProvider(userModeSession, "Microsoft-Antimalware-Service",
                                    new Guid("751ef305-6c6e-4fed-b847-02ef79d26aef"),
                                    TraceEventLevel.Verbose, ulong.MaxValue, options);

                                EnableUserProvider(userModeSession, "Microsoft-Antimalware-RTP",
                                    new Guid("8e92deef-5e17-413b-b927-59b2f06a3cfc"),
                                    TraceEventLevel.Verbose, ulong.MaxValue, options);

                                EnableUserProvider(userModeSession, "Microsoft-Antimalware-Protection",
                                    new Guid("e4b70372-261f-4c54-8fa6-a5a7914d73da"),
                                    TraceEventLevel.Verbose, ulong.MaxValue, options);

                                EnableUserProvider(userModeSession, "Microsoft-Windows-HttpService",
                                    new Guid("DD5EF90A-6398-47A4-AD34-4DCECDEF795F"),
                                    parsedArgs.ClrEventLevel, ulong.MaxValue, stacksEnabled);

                                // TODO this can be expensive.   turned it down (not clear what we lose).  
                                EnableUserProvider(userModeSession, "Microsoft-Windows-TCPIP",
                                    new Guid("2F07E2EE-15DB-40F1-90EF-9D7BA282188A"), TraceEventLevel.Informational, ulong.MaxValue, stacksEnabled);

                                // This actually will not cause any events to fire unless you first also enable
                                // the kernel in a special way.  Basically doing
                                // netsh trace start scenario=InternetClient capture=yes correlation=no report=disabled maxSize=250 traceFile=NetMonTrace.net.etl
                                EnableUserProvider(userModeSession, "Microsoft-Windows-NDIS-PacketCapture",
                                    new Guid("2ED6006E-4729-4609-B423-3EE7BCD678EF"),
                                    TraceEventLevel.Informational, ulong.MaxValue, options);

                                EnableUserProvider(userModeSession, "Microsoft-Windows-WebIO",
                                    new Guid("50B3E73C-9370-461D-BB9F-26F32D68887D"), TraceEventLevel.Informational, ulong.MaxValue, options);

                                // This provider is verbose in high volume networking scnearios and its value is dubious.  
                                //EnableUserProvider(userModeSession, "Microsoft-Windows-Winsock-AFD",
                                //    new Guid("E53C6823-7BB8-44BB-90DC-3F86090D48A6"),
                                //    parsedArgs.ClrEventLevel, ulong.MaxValue);

                                // This is probably too verbose, but we will see 
                                EnableUserProvider(userModeSession, "Microsoft-Windows-WinINet",
                                    new Guid("43D1A55C-76D6-4F7E-995C-64C711E5CAFE"), TraceEventLevel.Verbose, ulong.MaxValue, options);

                                // This is probably too verbose, but we will see 
                                EnableUserProvider(userModeSession, "Microsoft-Windows-WinHttp",
                                    new Guid("7D44233D-3055-4B9C-BA64-0D47CA40A232"), TraceEventLevel.Verbose, ulong.MaxValue, options);

                                // This has proven to be too expensive.  Wait until we need it.  
                                // EnableUserProvider(userModeSession, "Microsoft-Windows-Networking-Correlation",
                                //     new Guid("83ED54F0-4D48-4E45-B16E-726FFD1FA4AF"), (TraceEventLevel)255, 0);

                                EnableUserProvider(userModeSession, "Microsoft-Windows-RPC",
                                    new Guid("6AD52B32-D609-4BE9-AE07-CE8DAE937E39"), TraceEventLevel.Informational, 0, options);

                                // This is what WPA turns on in its 'GENERAL' setting  
                                //Microsoft-Windows-Immersive-Shell: 0x0000000000100000: 0x04
                                //Microsoft-Windows-Kernel-Power: 0x0000000000000004: 0xff
                                //Microsoft-Windows-Win32k: 0x0000000000402000: 0xff
                                //Microsoft-Windows-WLAN-AutoConfig: 0x0000000000000200: 0xff
                                //.NET Common Language Runtime: 0x0000000000000098: 0x05
                                //Microsoft-JScript: 0x0000000000000001: 0xff e7ef96be-969f-414f-97d7-3ddb7b558ccc: 0x0000000000002000: 0xff
                                //MUI Resource Trace: : 0xff
                                //Microsoft-Windows-COMRuntime: 0x0000000000000003: 0xff
                                //Microsoft-Windows-Networking-Correlation: : 0xff
                                //Microsoft-Windows-RPCSS: : 0x04
                                //Microsoft-Windows-RPC: : 0x04 a669021c-c450-4609-a035-5af59af4df18: : 0x00
                                //Microsoft-Windows-Kernel-Processor-Power: : 0xff
                                //Microsoft-Windows-Kernel-StoreMgr: : 0xff e7ef96be-969f-414f-97d7-3ddb7b558ccc: : 0xff
                                //Microsoft-Windows-UserModePowerService: : 0xff
                                //Microsoft-Windows-Win32k: : 0xff
                                //Microsoft-Windows-ReadyBoostDriver: : 0xff

#if false            // TODO FIX NOW remove 
                    var networkProviders = new List<string>();
                    networkProviders.Add("Microsoft-Windows-WebIO:*:5:stack");
                    networkProviders.Add("Microsoft-Windows-WinINet:*:5:stack");
                    networkProviders.Add("Microsoft-Windows-TCPIP:*:5:stack");
                    networkProviders.Add("Microsoft-Windows-NCSI:*:5:stack");
                    networkProviders.Add("Microsoft-Windows-WFP:*:5:stack");
                    networkProviders.Add("Microsoft-Windows-Iphlpsvc-Trace:*:5:stack");
                    networkProviders.Add("Microsoft-Windows-WinHttp:*:5:stack");
                    networkProviders.Add("Microsoft-Windows-NDIS-PacketCapture");
                    networkProviders.Add("Microsoft-Windows-NWiFi:*:5:stack");
                    networkProviders.Add("Microsoft-Windows-NlaSvc:*:5:stack");
                    networkProviders.Add("Microsoft-Windows-NDIS:*:5:stack");

                    EnableAdditionalProviders(userModeSession, networkProviders.ToArray());
#endif
                            }
                        }
                        else if ((parsedArgs.ClrEvents & ClrTraceEventParser.Keywords.GC) != 0)
                        {
                            LogFile.WriteLine("Turned on additional CLR GC events");
                            EnableUserProvider(userModeSession, "CLRPrivate", ClrPrivateTraceEventParser.ProviderGuid,
                                TraceEventLevel.Informational, (ulong)ClrPrivateTraceEventParser.Keywords.GC, options);
                        }

                        if ((parsedArgs.KernelEvents & KernelTraceEventParser.Keywords.ReferenceSet) != 0)
                        {
                            // ALso get heap ranges if ReferenceSet is on.  
                            EnableUserProvider(userModeSession, "Win32HeapRanges", HeapTraceProviderTraceEventParser.HeapRangeProviderGuid,
                                TraceEventLevel.Verbose, 0, options);
                        }

                        if (profilerKeywords != 0)
                        {
                            // Turn on allocation profiling if the user asked for it.   
                            EnableUserProvider(userModeSession, "ETWClrProfiler",
                                ETWClrProfilerTraceEventParser.ProviderGuid, TraceEventLevel.Verbose,
                                (ulong)profilerKeywords,
                                stacksEnabled);
                        }

                        LogFile.WriteLine("Turning on VS CodeMarkers and MeasurementBlock Providers.");
                        EnableUserProvider(userModeSession, "MeasurementBlock",
                            new Guid("143A31DB-0372-40B6-B8F1-B4B16ADB5F54"), TraceEventLevel.Verbose, ulong.MaxValue, options);
                        EnableUserProvider(userModeSession, "CodeMarkers",
                            new Guid("641D7F6C-481C-42E8-AB7E-D18DC5E5CB9E"), TraceEventLevel.Verbose, ulong.MaxValue, options);

                        // Turn off NGEN if they asked for it.  
                        if (parsedArgs.NoNGenRundown)
                        {
                            parsedArgs.ClrEvents &= ~ClrTraceEventParser.Keywords.NGen;
                        }

                        // Force NGEN rundown if they asked for it. 
                        if (parsedArgs.ForceNgenRundown)
                        {
                            parsedArgs.ClrEvents &= ~ClrTraceEventParser.Keywords.SupressNGen;
                        }

                        LogFile.WriteLine("Enabling CLR Events: {0}", parsedArgs.ClrEvents);
                        EnableUserProvider(userModeSession, "CLR", ClrTraceEventParser.ProviderGuid,
                            parsedArgs.ClrEventLevel, (ulong)parsedArgs.ClrEvents, options);
                    }

                    // Start network monitoring capture if needed
                    if (parsedArgs.NetMonCapture)
                    {
                        parsedArgs.NetworkCapture = true;
                    }

                    if (parsedArgs.NetworkCapture)
                    {
                        string maxSize = "maxSize=1";
                        string correlation = "correlation=no";
                        string report = "report=disabled";
                        string scenario = "InternetClient";
                        string perfMerge = "perfMerge=no";
                        string traceFile = CacheFiles.FindFile(parsedArgs.DataFile, ".netmon.etl");

                        var osVer = Environment.OSVersion.Version.Major * 10 + Environment.OSVersion.Version.Minor;
                        if (parsedArgs.NetMonCapture || osVer < 62)
                        {
                            traceFile = Path.GetFileNameWithoutExtension(parsedArgs.DataFile) + "_netmon.etl";  // We use the _ to avoid conventions about merging.  
                            maxSize = "";
                            correlation = "";
                            perfMerge = "";
                            report = "";
                        }
                        FileUtilities.ForceDelete(traceFile);

                        EnableUserProvider(userModeSession, "Microsoft-Windows-NDIS-PacketCapture",
                            new Guid("2ED6006E-4729-4609-B423-3EE7BCD678EF"), TraceEventLevel.Informational, ulong.MaxValue, options);
                        EnableUserProvider(userModeSession, "Microsoft-Windows-TCPIP",
                            new Guid("2F07E2EE-15DB-40F1-90EF-9D7BA282188A"), TraceEventLevel.Informational, ulong.MaxValue, stacksEnabled);

                        string commandLine = string.Format("netsh trace start scenario={0} capture=yes {1} {2} {3} {4} \"traceFile={5}\"",
                            scenario, correlation, report, maxSize, perfMerge, traceFile);

                        LogFile.WriteLine("Turning on network packet monitoring");
                        LogFile.WriteLine("Can turn off running 'netsh trace stop' or rebooting.");

                        LogFile.WriteLine("Executing the command: {0}", commandLine);

                        // Make sure that if we are on a 64 bit machine we run the 64 bit version of netsh.  
                        var cmdExe = Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), "SysNative", "cmd.exe");
                        if (!File.Exists(cmdExe))
                        {
                            cmdExe = cmdExe.Replace("SysNative", "System32");
                        }

                        commandLine = cmdExe + " /c " + commandLine;
                        var command = Command.Run(commandLine, new CommandOptions().AddNoThrow().AddOutputStream(LogFile));

                        string netMonFile = Path.Combine(CacheFiles.CacheDir, "NetMonActive.txt");
                        File.WriteAllText(netMonFile, "");      // mark that Network monitoring is potentially active 

                        if (command.ExitCode != 0)
                        {
                            throw new ApplicationException("Could not turn on network packet monitoring with the 'netsh trace' command.");
                        }

                        LogFile.WriteLine("netsh trace command succeeded.");
                    }
                    if (parsedArgs.CCWRefCount)
                    {
                        EnableUserProvider(userModeSession, "InteropEventProvider", new Guid("c4ac552a-e1eb-4fa2-a651-b200efd7aa91"), TraceEventLevel.Verbose, ulong.MaxValue, stacksEnabled);
                    }

                    LogFile.WriteLine("Enabling Providers specified by the user.");
                    if (parsedArgs.Providers != null)
                    {
                        EnableAdditionalProviders(userModeSession, parsedArgs.Providers, parsedArgs.CommandLine, options);
                    }

                    // OK at this point, we want to leave both sessions for an indefinite period of time (even past process exit)
                    kernelModeSession.StopOnDispose = false;
                    userModeSession.StopOnDispose = false;
                    if (heapSession != null)
                    {
                        heapSession.StopOnDispose = false;
                    }

                    PerfViewLogger.Log.CommandLineParameters(ParsedArgsAsString(null, parsedArgs), Environment.CurrentDirectory, AppLog.VersionNumber);
                }
            }
        }