static int MainWorker()

in DbgShell/MainClass.cs [640:830]


        static int MainWorker( string[] args )
        {
            try
            {
                var profileDir = Path.Combine( Environment.GetFolderPath( Environment.SpecialFolder.LocalApplicationData,
                                                                          Environment.SpecialFolderOption.DoNotVerify ),
                                              "Temp",
                                              "DbgProvider",
                                              "ProfileOpt" );
                Directory.CreateDirectory( profileDir );

                System.Runtime.ProfileOptimization.SetProfileRoot( profileDir );

                System.Runtime.ProfileOptimization.StartProfile( "StartupProfileData-" +
                                                                 (DbgProvider.IsInGuestMode ? "GuestMode"
                                                                                            : "NormalMode") );
            }
            catch
            {
                Util.Fail( "SetProfileRoot/StartProfile failed" );
                // It's safe to ignore errors, the guarded code is just there to try and
                // improve startup performance.
            }

            string rootDir;
            try
            {
                rootDir = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location );
            }
            catch( Exception e )
            {
                Console.WriteLine( "Exception! {0}", e );
                return -1;
            }

            //Console.WriteLine( "rootDir: {0}", rootDir );

            /*
            string pathToMsvcr120 = Assembly.GetExecutingAssembly().Location;
            pathToMsvcr120 = Path.GetDirectoryName( pathToMsvcr120 );
#if DEBUG
            pathToMsvcr120 = Path.Combine( pathToMsvcr120, "Debugger", "MSVCR120d.dll" );
#else
            pathToMsvcr120 = Path.Combine( pathToMsvcr120, "Debugger", "MSVCR120.dll" );
#endif

            IntPtr hMsvcr = NativeMethods.LoadLibraryEx( pathToMsvcr120,
                                                          IntPtr.Zero,
                                                          LoadLibraryExFlags.LOAD_WITH_ALTERED_SEARCH_PATH );
            if( IntPtr.Zero == hMsvcr )
                throw new Exception( "Could not load MSVCR120.dll." );
            */


            _ConfigureModulePath( rootDir );

            _RemoveMarkOfTheInternet( rootDir );

            string dbgModuleDir = Path.Combine( rootDir, "Debugger" );


            RunspaceConfiguration config = RunspaceConfiguration.Create();
            // TODO, FILE_A_PS_BUG: Why can't I set the shell ID?
            //config.ShellId = "MS.DbgShell";

            config.InitializationScripts.Append(
                    new ScriptConfigurationEntry( "BypassExecutionPolicy",
                                                  "Set-ExecutionPolicy -Scope Process Bypass -Force ; Set-StrictMode -Version Latest" ) );

            config.InitializationScripts.Append(
                    new ScriptConfigurationEntry( "ImportOurModule",
                                                  Util.Sprintf( @"Import-Module ""{0}""",
                                                                Path.Combine( dbgModuleDir, "Debugger.psd1" ) ) ) );

            config.InitializationScripts.Append(
                    new ScriptConfigurationEntry( "CreateBinDrive",
                                                  String.Format( CultureInfo.InvariantCulture,
                                                                 @"[void] (New-PSDrive Bin FileSystem ""{0}"")",
                                                                 rootDir ) ) );

            config.InitializationScripts.Append(
                    new ScriptConfigurationEntry( "SetStartLocation", "Set-Location Dbg:\\" ) );

            if( DbgProvider.IsInGuestMode )
            {
                // In guest mode, we are already attached to something, so we need to
                // build the namespace based on the existing dbgeng state.
                config.InitializationScripts.Append(
                        new ScriptConfigurationEntry( "RebuildNs", "[MS.Dbg.DbgProvider]::ForceRebuildNamespace()" ) );
            }

            // I cannot explain why, but using Update-FormatData (which is [a proxy
            // function] defined in our module instead of Invoke-Script (a C# cmdlet
            // defined in our module) subtly changes something having to do with scope or
            // something, such that the $AltListIndent variable wasn't working... until
            // all the format data was reloaded via Update-FormatData.
            var fmtScripts = _GetFmtScripts( dbgModuleDir );
            config.InitializationScripts.Append(
                    new ScriptConfigurationEntry( "LoadFmtDefinitions",
                                                  String.Format( CultureInfo.InvariantCulture,
                                                                 @"[void] (Update-FormatData ""{0}"")",
                                                                 String.Join( "\", \"", fmtScripts ) ) ) );

            // And in fact it seems that the trick to not losing our "captured contexts"
            // is that Update-AltFormatData needs to always be run in the context of the
            // Debugger.Formatting module.
            string monkeyPatched = @"function Update-AltFormatData {
    [CmdletBinding()]
    param( [Parameter( Mandatory = $false )]
           [string[]] $AppendPath = @(),

           [Parameter( Mandatory = $false )]
           [string[]] $PrependPath = @()
         )

    process
    {
        try
        {
            # This is pretty ugly. In particular, I can't find a better way to pass in
            # -Verbose. Ideally it could just be captured magically, but things like
            # <scriptblock>.GetNewClosure() don't seem to help.

            Invoke-InAlternateScope -ScriptBlock { $VerbosePreference = $args[2] ; Debugger\Update-AltFormatData -AppendPath $args[0] -PrependPath $args[1] } `
                                    -Arguments @( $AppendPath, $PrependPath, $VerbosePreference ) `
                                    -ScopingModule ((Get-Module Debugger).NestedModules | where name -eq 'Debugger.Formatting')
        }
        finally { }
    } # end 'process' block
<#
.ForwardHelpTargetName Update-AltFormatData
.ForwardHelpCategory Cmdlet
#>
}";
            config.InitializationScripts.Append(
                    new ScriptConfigurationEntry( "MonkeyPatchUpdateAltFormatData",
                                                  monkeyPatched ) );


            string typesPs1Xml = Path.Combine( dbgModuleDir, "Types.ps1xml" );

            if( File.Exists( typesPs1Xml ) ) // TODO: Remove once types.ps1xml is picked in
            {
                config.InitializationScripts.Append(
                        new ScriptConfigurationEntry( "LoadTypeAdapterStuff",
                                                      String.Format( CultureInfo.InvariantCulture,
                                                                     @"[void] (Update-TypeData ""{0}"")",
                                                                     c_FileSystem_PowerShellProviderPrefix + typesPs1Xml ) ) );
            }

            var converterScripts = Directory.GetFiles( dbgModuleDir, "Debugger.Converters.*.ps1" );
            StringBuilder loadConvertersCmd = new StringBuilder();
            foreach( var converterScript in converterScripts )
            {
                loadConvertersCmd.Append( Util.Sprintf( "; [void] (& '{0}{1}')", c_FileSystem_PowerShellProviderPrefix, converterScript ) );
            }

            string argCompleterScript = Path.Combine( dbgModuleDir, "Debugger.ArgumentCompleters.ps1" );
            loadConvertersCmd.Append( Util.Sprintf( "; [void] (& '{0}{1}')", c_FileSystem_PowerShellProviderPrefix, argCompleterScript) );

            config.InitializationScripts.Append(
                    new ScriptConfigurationEntry( "LoadConverters", loadConvertersCmd.ToString() ) );

            // TODO: wrap
            var colorBanner = new ColorString( ConsoleColor.Cyan, "Microsoft Debugger DbgShell\n" )
                    .AppendFg( ConsoleColor.DarkCyan ).Append( "Copyright (c) 2015\n\n" )
                    .AppendFg( ConsoleColor.Magenta ).Append( "Welcome.\n\n" )
                    .AppendFg( ConsoleColor.Gray ).Append( "Note that script execution policy is '" )
                    .AppendFg( ConsoleColor.Yellow ).Append( "Bypass" )
                    .AppendFg( ConsoleColor.Gray ).Append( "' for this process.\nRun '" )
                    .AppendFg( ConsoleColor.Yellow ).Append( "Get-Help" )
                    .AppendFg( ConsoleColor.Gray ).Append( " about_DbgShell_GettingStarted' to learn about DbgShell.\n" );

            if( DbgProvider.IsInGuestMode )
            {
                colorBanner
                    .AppendFg( ConsoleColor.Gray ).Append( "\nWhen you are finished here and want to return control back to the debugger, run '" )
                    .AppendFg( ConsoleColor.Yellow ).Append( "q" )
                    .AppendFg( ConsoleColor.Gray ).Append( "' or '" )
                    .AppendFg( ConsoleColor.Green ).Append( "exit" )
                    .AppendFg( ConsoleColor.Gray ).Append( "'." );
            }

            string banner = colorBanner.ToString( true );

            int rc = ColorConsoleHost.Start( config,
                                             banner,
                                             String.Empty,
                                             args );
            return rc;
        } // end MainWorker()