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()