Beispiel #1
0
        } // end constructor

        //
        // IEquatable-related stuff
        //

        public bool Equals(PropertyListItem other)
        {
            if (other == null)
            {
                return(false);
            }

            return((PropertyName == other.PropertyName) &&
                   (FormatString?.ToString(true) == other.FormatString?.ToString(true)) &&
                   (m_label == other.m_label));
        }
Beispiel #2
0
        protected StringBuilder ObjectToMarkedUpString(object obj, ColorString formatString, StringBuilder sb)
        {
            if (null == sb)
            {
                sb = new StringBuilder();
            }

            if (null == obj)
            {
                //return sb;
                return(sb.Append("$null"));
            }

            PSObject pso = obj as PSObject;

            if (null != pso)
            {
                // Check if there is a custom .ToString() method attached to this
                // PSObject. (which is used, for instance, for displaying enum values)

                var toStringMethods = Util.TryGetCustomToStringMethod(pso);

                if (null != toStringMethods)
                {
                    // TODO: check overloads/signature?
                    obj = toStringMethods.Invoke();
                    if (obj is string)
                    {
                        return(sb.Append((string)obj));
                    }
                    else
                    {
                        LogManager.Trace("Interesting... a custom .ToString() method returned something besides a string.");
                    }
                }
                else
                {
                    obj = pso.BaseObject;
                }
            }

            ColorString cs = obj as ColorString;

            if (null != cs)
            {
                sb.Append(cs.ToString(DbgProvider.HostSupportsColor));
            }
            else
            {
                ISupportColor isc = obj as ISupportColor;
                if (null != isc)
                {
                    sb.Append(isc.ToColorString().ToString(DbgProvider.HostSupportsColor));
                }
                else
                {
                    string renderedFormatString = null;
                    if (null != formatString)
                    {
                        renderedFormatString = formatString.ToString(DbgProvider.HostSupportsColor);
                    }

                    if (!String.IsNullOrEmpty(renderedFormatString))
                    {
                        sb.Append(Util.CcSprintf(renderedFormatString, obj));
                    }
                    else
                    {
                        // TODO: Or should it be pso.ToString here?
                        sb.Append(obj.ToString());
                    }
                }
            }
            return(sb);
        } // end ObjectToMarkedUpString()
Beispiel #3
0
        } // end GenerateView()

        protected override void ApplyViewToInputObject()
        {
            for (int idx = 0; idx < m_view.ListItems.Count; idx++)
            {
                if (Stopping)
                {
                    break;
                }

                ColorString listItem = new ColorString(sm_labelColors);

                ListItem li = m_view.ListItems[idx];
                listItem.Append(PadAndAlign(li.Label,
                                            m_view.MaxLabelLength + 1,
                                            ColumnAlignment.Left) + ": ");

                listItem.Append(sm_pop.ToString(DbgProvider.HostSupportsColor));

                string val;
                if (li is PropertyListItem)
                {
                    var pli = (PropertyListItem)li;
                    val = RenderPropertyValue(InputObject,
                                              pli.PropertyName,
                                              pli.FormatString,
                                              dontGroupMultipleResults: false,
                                              allowMultipleLines: true);   // <-- N.B. special for Format-List compat
                }
                else
                {
                    var sli = (ScriptListItem)li;
                    val = RenderScriptValue(InputObject, sli.Script);
                    if (null == val)
                    {
                        val = String.Empty;
                    }
                }

                listItem.Append(_Indent(val));
                SafeWriteObject(listItem);
            }
            // N.B. Using String.Empty here used to cause 3 blank lines instead of one.
            // I don't understand precisely why, but the crux of the problem is that
            //
            //     a) System.String has a custom view definition (which is to get around
            //        PowerShell's reticence to properly display strings if they have
            //        other stuff in their TypeNames) (see commit 4bc7d1c76f97d0)
            //     b) When we write the string here, for some reason it causes a
            //        transition between steppable pipelines, and the PS default
            //        formatter wants to put in an extra newline at the format start and
            //        another at the format end.
            //
            // Fortunately, it seems easy enough to workaround by sending a different type
            // of object down the pipeline.
            //
            // (I wonder if it might have been specific to the particular commands I was
            // using to test, like "uf blah!blah | fl", or symbols | fl, because of how
            // their formatting was done.)
            //
            //SafeWriteObject( String.Empty ); // to get a blank line
            SafeWriteObject(ColorString.Empty);   // to get a blank line
        } // end ApplyViewToInputObject()
        } // end _AltMainThread()

        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");


            // TODO: investigate differences between CreateDefault and CreateDefault2
            InitialSessionState iss = InitialSessionState.CreateDefault();

            iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Bypass;

            // TODO: maybe add to iss.Formats?

            List <InitScript> initScripts = new List <InitScript>();


            initScripts.Add(new InitScript("SetStrictMode",
                                           "Set-StrictMode -Version Latest"));

            initScripts.Add(new InitScript("ImportOurModule",
                                           Util.Sprintf(@"Import-Module ""{0}""",
                                                        Path.Combine(dbgModuleDir, "Debugger.psd1"))));

            initScripts.Add(new InitScript("CreateBinDrive",
                                           String.Format(CultureInfo.InvariantCulture,
                                                         @"[void] (New-PSDrive Bin FileSystem ""{0}"")",
                                                         rootDir)));

            initScripts.Add(new InitScript("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.
                initScripts.Add(new InitScript("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);

            initScripts.Add(
                new InitScript("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
#>
}";

            initScripts.Add(new InitScript("MonkeyPatchUpdateAltFormatData",
                                           monkeyPatched));


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

            if (File.Exists(typesPs1Xml))    // TODO: Remove once types.ps1xml is picked in
            {
                initScripts.Add(
                    new InitScript("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));

            initScripts.Add(new InitScript("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(iss,
                                            initScripts,
                                            banner,
                                            String.Empty,
                                            args);

            return(rc);
        } // end MainWorker()
Beispiel #5
0
        protected StringBuilder ObjectToMarkedUpString(object obj, ColorString formatString, StringBuilder sb)
        {
            if (null == sb)
            {
                sb = new StringBuilder();
            }

            if (null == obj)
            {
                // We used to return sb.Append( "$null" ); however I'm changing to append
                // nothing in order to match the behavior of FormatSingleLineDirect (which
                // is what is applied to obj if there is no formatString, which yields an
                // empty string, so when we come through here, obj is an empty string, not
                // null).
                return(sb);
            }

            PSObject pso = obj as PSObject;

            if (null != pso)
            {
                // Check if there is a custom .ToString() method attached to this
                // PSObject. (which is used, for instance, for displaying enum values)

                var toStringMethods = Util.TryGetCustomToStringMethod(pso);

                if (null != toStringMethods)
                {
                    // TODO: check overloads/signature?
                    obj = toStringMethods.Invoke();
                    if (obj is string)
                    {
                        return(sb.Append((string)obj));
                    }
                    else
                    {
                        LogManager.Trace("Interesting... a custom .ToString() method returned something besides a string.");
                    }
                }
                else
                {
                    obj = pso.BaseObject;
                }
            }

            ColorString cs = obj as ColorString;

            if (null != cs)
            {
                sb.Append(cs.ToString(DbgProvider.HostSupportsColor));
            }
            else
            {
                ISupportColor isc = obj as ISupportColor;
                if (null != isc)
                {
                    sb.Append(isc.ToColorString().ToString(DbgProvider.HostSupportsColor));
                }
                else
                {
                    string renderedFormatString = null;
                    if (null != formatString)
                    {
                        renderedFormatString = formatString.ToString(DbgProvider.HostSupportsColor);
                    }

                    if (!String.IsNullOrEmpty(renderedFormatString))
                    {
                        sb.Append(Util.CcSprintf(renderedFormatString, obj));
                    }
                    else
                    {
                        // TODO: Or should it be pso.ToString here?
                        sb.Append(obj.ToString());
                    }
                }
            }
            return(sb);
        } // end ObjectToMarkedUpString()
Beispiel #6
0
        public Answers Ask()
        {
            var answers = new Answers(_promptItems.Count);

            EventHandler <BeforeAfterPromptEventArgs> beforePrompt   = BeforePrompt;
            EventHandler <BetweenPromptEventArgs>     betweenPrompts = BetweenPrompts;
            EventHandler <BeforeAfterPromptEventArgs> afterPrompt    = AfterPrompt;

            for (int i = 0; i < _promptItems.Count; i++)
            {
                PromptItem promptItem = _promptItems[i];

                beforePrompt?.Invoke(this, new BeforeAfterPromptEventArgs {
                    Prompt = promptItem
                });

                object answer;

                // If the prompt cannot be displayed, continue the loop.
                // If it is a question, try assigning the default value, if available, before
                // continuing.
                if (!promptItem.CanAsk(answers))
                {
                    if (promptItem is Question q)
                    {
                        answer = q.DefaultValue.Resolve(answers);
                        if (answer != null)
                        {
                            answers.Add(q.Name, answer);
                        }
                    }

                    continue;
                }

                // If the prompt is static text, just display it and continue the loop.
                if (promptItem is StaticText)
                {
                    promptItem.AskerFn(promptItem, answers);
                    continue;
                }

                var question = promptItem as Question;

                if (question.Instructions.Count > 0)
                {
                    foreach (FunctionOrColorString instruction in question.Instructions)
                    {
                        var cstr = new ColorString().Text(instruction.Resolve(answers),
                                                          Style.Instructions.ForeColor, Style.Instructions.BackColor);
                        ConsoleEx.PrintLine(cstr.ToString());
                    }
                }

                answer = null;
                bool validAnswer = false;
                do
                {
                    object input = question.AskerFn(question, answers);

                    if (question.RawValueValidator != null)
                    {
                        ValidationResult validationResult = question.RawValueValidator(input, answers);
                        if (!validationResult.Valid)
                        {
                            if (!string.IsNullOrWhiteSpace(validationResult.ErrorMessage))
                            {
                                ConsoleEx.PrintLine($"{Clr.Red}{validationResult.ErrorMessage}");
                            }
                            continue;
                        }
                    }

                    if (input is null || (input is string s && s.Length == 0))
                    {
                        answer = question.DefaultValue.Resolve(answers);
                    }
                    else
                    {
                        answer = input;
                    }

                    answer = question.Convert(answer);

                    if (question.ConvertedValueValidator != null)
                    {
                        ValidationResult validationResult = question.ConvertedValueValidator(answer, answers);
                        if (!validationResult.Valid)
                        {
                            if (!string.IsNullOrWhiteSpace(validationResult.ErrorMessage))
                            {
                                ConsoleEx.PrintLine($"{Clr.Red}{validationResult.ErrorMessage}");
                            }
                            continue;
                        }
                    }

                    validAnswer = true;
                }
#pragma warning disable S2583 // Conditionally executed blocks should be reachable
                while (!validAnswer);
#pragma warning restore S2583 // Conditionally executed blocks should be reachable

                answers.Add(question.Name, answer);

                if (i < _promptItems.Count - 1)
                {
                    betweenPrompts?.Invoke(this, new BetweenPromptEventArgs
                    {
                        PreviousPrompt = promptItem,
                        NextPrompt     = _promptItems[i + 1],
                    });
                }

                afterPrompt?.Invoke(this, new BeforeAfterPromptEventArgs {
                    Prompt = promptItem
                });
            }
        public void ToString_BuildsColorString(ColorString cs, string expectedString)
        {
            string colorString = cs.ToString();

            colorString.ShouldBe(expectedString);
        }