Esempio n. 1
0
        protected async Task HandleEvaluateRequest(
            DebugAdapterMessages.EvaluateRequestArguments evaluateParams,
            EditorSession editorSession,
            RequestContext <DebugAdapterMessages.EvaluateResponseBody, object> requestContext)
        {
            VariableDetails result =
                await editorSession.DebugService.EvaluateExpression(
                    evaluateParams.Expression,
                    evaluateParams.FrameId);

            string valueString = null;
            int    variableId  = 0;

            if (result != null)
            {
                valueString = result.ValueString;
                variableId  =
                    result.IsExpandable ?
                    result.Id : 0;
            }

            await requestContext.SendResult(
                new DebugAdapterMessages.EvaluateResponseBody
            {
                Result             = valueString,
                VariablesReference = variableId
            });
        }
Esempio n. 2
0
        protected async Task HandleEvaluateRequest(
            EvaluateRequestArguments evaluateParams,
            RequestContext <EvaluateResponseBody> requestContext)
        {
            string valueString = null;
            int    variableId  = 0;

            bool isFromRepl =
                string.Equals(
                    evaluateParams.Context,
                    "repl",
                    StringComparison.CurrentCultureIgnoreCase);

            if (isFromRepl)
            {
                // Check for special commands
                if (string.Equals("!ctrlc", evaluateParams.Expression, StringComparison.CurrentCultureIgnoreCase))
                {
                    editorSession.PowerShellContext.AbortExecution();
                }
                else if (string.Equals("!break", evaluateParams.Expression, StringComparison.CurrentCultureIgnoreCase))
                {
                    editorSession.DebugService.Break();
                }
                else
                {
                    // Send the input through the console service
                    editorSession.ConsoleService.ExecuteCommand(
                        evaluateParams.Expression,
                        false);
                }
            }
            else
            {
                VariableDetails result =
                    await editorSession.DebugService.EvaluateExpression(
                        evaluateParams.Expression,
                        evaluateParams.FrameId,
                        isFromRepl);

                if (result != null)
                {
                    valueString = result.ValueString;
                    variableId  =
                        result.IsExpandable ?
                        result.Id : 0;
                }
            }

            await requestContext.SendResult(
                new EvaluateResponseBody
            {
                Result             = valueString,
                VariablesReference = variableId
            });
        }
        private VariableDetails GetDetails(int localIndex)
        {
            var detailsItem = this.details.GetValueOrDefault(localIndex);
            if (detailsItem == null) {
                detailsItem = new VariableDetails();
                this.details.Add(localIndex, detailsItem);
            }

            return detailsItem;
        }
 public static Variable Create(VariableDetails variable)
 {
     return(new Variable
     {
         Name = variable.Name,
         Value = variable.ValueString ?? string.Empty,
         VariablesReference =
             variable.IsExpandable ?
             variable.Id : 0
     });
 }
        protected async Task HandleEvaluateRequest(
            EvaluateRequestArguments evaluateParams,
            RequestContext <EvaluateResponseBody> requestContext)
        {
            string valueString = null;
            int    variableId  = 0;

            bool isFromRepl =
                string.Equals(
                    evaluateParams.Context,
                    "repl",
                    StringComparison.CurrentCultureIgnoreCase);

            if (isFromRepl)
            {
                // TODO: Do we send the input through the command handler?
                // Send the input through the console service
                var notAwaited =
                    this.editorSession
                    .PowerShellContext
                    .ExecuteScriptString(evaluateParams.Expression, false, true)
                    .ConfigureAwait(false);
            }
            else
            {
                VariableDetails result = null;

                // VS Code might send this request after the debugger
                // has been resumed, return an empty result in this case.
                if (editorSession.PowerShellContext.IsDebuggerStopped)
                {
                    result =
                        await editorSession.DebugService.EvaluateExpression(
                            evaluateParams.Expression,
                            evaluateParams.FrameId,
                            isFromRepl);
                }

                if (result != null)
                {
                    valueString = result.ValueString;
                    variableId  =
                        result.IsExpandable ?
                        result.Id : 0;
                }
            }

            await requestContext.SendResult(
                new EvaluateResponseBody
            {
                Result             = valueString,
                VariablesReference = variableId
            });
        }
 public static Variable Create(VariableDetails variable)
 {
     return new Variable
     {
         Name = variable.Name,
         Value = variable.ValueString ?? string.Empty,
         VariablesReference =
             variable.IsExpandable ?
                 variable.Id : 0
     };
 }
        private VariableDetails GetDetails(int localIndex)
        {
            var detailsItem = this.details.GetValueOrDefault(localIndex);

            if (detailsItem == null)
            {
                detailsItem = new VariableDetails();
                this.details.Add(localIndex, detailsItem);
            }

            return(detailsItem);
        }
Esempio n. 8
0
        private async Task <VariableContainerDetails> FetchVariableContainerAsync(
            string scope,
            VariableContainerDetails autoVariables)
        {
            PSCommand psCommand = new PSCommand();

            psCommand.AddCommand("Get-Variable");
            psCommand.AddParameter("Scope", scope);

            var scopeVariableContainer =
                new VariableContainerDetails(this.nextVariableId++, "Scope: " + scope);

            this.variables.Add(scopeVariableContainer);

            var results = await this.powerShellContext.ExecuteCommandAsync <PSObject>(psCommand, sendErrorToHost : false).ConfigureAwait(false);

            if (results != null)
            {
                foreach (PSObject psVariableObject in results)
                {
                    var variableDetails = new VariableDetails(psVariableObject)
                    {
                        Id = this.nextVariableId++
                    };
                    this.variables.Add(variableDetails);
                    scopeVariableContainer.Children.Add(variableDetails.Name, variableDetails);

                    if ((autoVariables != null) && AddToAutoVariables(psVariableObject, scope))
                    {
                        autoVariables.Children.Add(variableDetails.Name, variableDetails);
                    }
                }
            }

            return(scopeVariableContainer);
        }
        public List <VariableDetails> GetVariableDetails(VariableInfo info)
        {
            if (info == null)
            {
                return(null);
            }
            ;

            var list = new List <VariableDetails>();

            if (_service.Cpus.ContainsKey(info.CpuName))
            {
                var cpu = _service.Cpus[info.CpuName];

                foreach (var variable in info.Variables)
                {
                    if (cpu.Variables.ContainsKey(variable))
                    {
                        var value = ConvertVariableValue(cpu.Variables[variable].Value);

                        var details = new VariableDetails();
                        details.Name        = cpu.Variables[variable].Name;
                        details.CpuName     = info.CpuName;
                        details.Value       = value;
                        details.IsConnected = cpu.Variables[variable].IsConnected;
                        details.HasError    = cpu.Variables[variable].HasError;
                        details.ErrorCode   = cpu.Variables[variable].ErrorCode.ToString();
                        details.ErrorText   = cpu.Variables[variable].ErrorText;

                        list.Add(details);
                    }
                }
            }

            return(list);
        }
Esempio n. 10
0
        public object GetVariableValue(string guid, string variableName)
        {
            if (!IsLoggedInUserAuthorized)
            {
                return(string.Empty);
            }

            var sessionExists = ScriptSessionManager.SessionExists(guid);

            if (!sessionExists)
            {
                return("<div class='undefinedVariableType'>Session not found</div>" +
                       "<div class='variableLine'>A script needs to be executed in the session<br/>before the variable value can be inspected.</div>");
            }

            var session = ScriptSessionManager.GetSession(guid);

            try
            {
                variableName = variableName.TrimStart('$');
                var debugVariable = session.GetDebugVariable(variableName);
                if (debugVariable == null)
                {
                    return("<div class='undefinedVariableType'>undefined</div>" +
                           $"<div class='variableLine'><span class='varName'>${variableName}</span> : <span class='varValue'>$null</span></div>");
                }

                var defaultProps = new string[0];
                if (debugVariable is PSObject)
                {
                    var script =
                        $"${variableName}.PSStandardMembers.DefaultDisplayPropertySet.ReferencedPropertyNames";
                    session.Output.SilenceOutput = true;
                    try
                    {
                        if (session.TryInvokeInRunningSession(script, out List <object> results) && results != null)
                        {
                            defaultProps = session.IsRunning
                                ? (session.Output.SilencedOutput?.ToString()
                                   .Split('\n')
                                   .Select(line => line.Trim())
                                   .ToArray() ?? new string[0])
                                : results.Cast <string>().ToArray();
                            session.Output.SilencedOutput?.Clear();
                        }
                    }
                    finally
                    {
                        session.Output.SilenceOutput = false;
                    }
                }
                var variable = debugVariable.BaseObject();
                if (variable is PSCustomObject)
                {
                    variable = debugVariable;
                }
                var details  = new VariableDetails("$" + variableName, variable);
                var varValue = $"<div class='variableType'>{variable.GetType().FullName}</div>";
                varValue +=
                    $"<div class='variableLine'><span class='varName'>${variableName}</span> : <span class='varValue'>{details.HtmlEncodedValueString}</span></div>";

                if (!details.IsExpandable)
                {
                    return(varValue);
                }

                // sort only if the object is not an array otherwise the indexes will get scrambled.
                var children = details.ShowDotNetProperties
                    ? details.GetChildren().OrderBy(d => d.Name).ToArray()
                    : details.GetChildren();

                foreach (var child in children)
                {
                    if (!child.IsExpandable ||
                        defaultProps.Contains(child.Name, StringComparer.OrdinalIgnoreCase) ||
                        ImportantProperties.Contains(child.Name, StringComparer.OrdinalIgnoreCase))
                    {
                        varValue +=
                            $"<span class='varChild'><span class='childName'>{child.Name}</span> : <span class='childValue'>{child.HtmlEncodedValueString}</span></span>";
                    }
                    else
                    {
                        if (details.ShowDotNetProperties)
                        {
                            continue;
                        }
                        varValue +=
                            $"<span class='varChild'><span class='childName'>{child.Name}</span> : <span class='childValue'>{{";
                        foreach (var subChild in child.GetChildren())
                        {
                            if (!subChild.IsExpandable)
                            {
                                varValue +=
                                    $"<span class='childName'>{subChild.Name}</span> : {subChild.HtmlEncodedValueString}, ";
                            }
                        }
                        varValue  = varValue.TrimEnd(' ', ',');
                        varValue += "}</span></span>";
                    }
                }
                if (details.MaxArrayParseSizeExceeded)
                {
                    varValue +=
                        $"<span class='varChild'><span class='varName'>... first {VariableDetails.MaxArrayParseSize} items shown.</span></span>";
                }
                return(varValue);
            }
            catch (Exception ex)
            {
                return(ex.Message);
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Sets the specified variable by container variableReferenceId and variable name to the
        /// specified new value.  If the variable cannot be set or converted to that value this
        /// method will throw InvalidPowerShellExpressionException, ArgumentTransformationMetadataException, or
        /// SessionStateUnauthorizedAccessException.
        /// </summary>
        /// <param name="variableContainerReferenceId">The container (Autos, Local, Script, Global) that holds the variable.</param>
        /// <param name="name">The name of the variable prefixed with $.</param>
        /// <param name="value">The new string value.  This value must not be null.  If you want to set the variable to $null
        /// pass in the string "$null".</param>
        /// <returns>The string representation of the value the variable was set to.</returns>
        public async Task <string> SetVariableAsync(int variableContainerReferenceId, string name, string value)
        {
            Validate.IsNotNull(nameof(name), name);
            Validate.IsNotNull(nameof(value), value);

            this.logger.LogTrace($"SetVariableRequest for '{name}' to value string (pre-quote processing): '{value}'");

            // An empty or whitespace only value is not a valid expression for SetVariable.
            if (value.Trim().Length == 0)
            {
                throw new InvalidPowerShellExpressionException("Expected an expression.");
            }

            // Evaluate the expression to get back a PowerShell object from the expression string.
            PSCommand psCommand = new PSCommand();

            psCommand.AddScript(value);
            var errorMessages = new StringBuilder();
            var results       =
                await this.powerShellContext.ExecuteCommandAsync <object>(
                    psCommand,
                    errorMessages,
                    false,
                    false).ConfigureAwait(false);

            // Check if PowerShell's evaluation of the expression resulted in an error.
            object psobject = results.FirstOrDefault();

            if ((psobject == null) && (errorMessages.Length > 0))
            {
                throw new InvalidPowerShellExpressionException(errorMessages.ToString());
            }

            // If PowerShellContext.ExecuteCommand returns an ErrorRecord as output, the expression failed evaluation.
            // Ideally we would have a separate means from communicating error records apart from normal output.
            if (psobject is ErrorRecord errorRecord)
            {
                throw new InvalidPowerShellExpressionException(errorRecord.ToString());
            }

            // OK, now we have a PS object from the supplied value string (expression) to assign to a variable.
            // Get the variable referenced by variableContainerReferenceId and variable name.
            VariableContainerDetails variableContainer = null;

            await this.debugInfoHandle.WaitAsync().ConfigureAwait(false);

            try
            {
                variableContainer = (VariableContainerDetails)this.variables[variableContainerReferenceId];
            }
            finally
            {
                this.debugInfoHandle.Release();
            }

            VariableDetailsBase variable = variableContainer.Children[name];
            // Determine scope in which the variable lives. This is required later for the call to Get-Variable -Scope.
            string scope = null;

            if (variableContainerReferenceId == this.scriptScopeVariables.Id)
            {
                scope = "Script";
            }
            else if (variableContainerReferenceId == this.globalScopeVariables.Id)
            {
                scope = "Global";
            }
            else
            {
                // Determine which stackframe's local scope the variable is in.
                StackFrameDetails[] stackFrames = await this.GetStackFramesAsync().ConfigureAwait(false);

                for (int i = 0; i < stackFrames.Length; i++)
                {
                    var stackFrame = stackFrames[i];
                    if (stackFrame.LocalVariables.ContainsVariable(variable.Id))
                    {
                        scope = i.ToString();
                        break;
                    }
                }
            }

            if (scope == null)
            {
                // Hmm, this would be unexpected.  No scope means do not pass GO, do not collect $200.
                throw new Exception("Could not find the scope for this variable.");
            }

            // Now that we have the scope, get the associated PSVariable object for the variable to be set.
            psCommand.Commands.Clear();
            psCommand = new PSCommand();
            psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Get-Variable");
            psCommand.AddParameter("Name", name.TrimStart('$'));
            psCommand.AddParameter("Scope", scope);

            IEnumerable <PSVariable> result = await this.powerShellContext.ExecuteCommandAsync <PSVariable>(psCommand, sendErrorToHost : false).ConfigureAwait(false);

            PSVariable psVariable = result.FirstOrDefault();

            if (psVariable == null)
            {
                throw new Exception($"Failed to retrieve PSVariable object for '{name}' from scope '{scope}'.");
            }

            // We have the PSVariable object for the variable the user wants to set and an object to assign to that variable.
            // The last step is to determine whether the PSVariable is "strongly typed" which may require a conversion.
            // If it is not strongly typed, we simply assign the object directly to the PSVariable potentially changing its type.
            // Turns out ArgumentTypeConverterAttribute is not public. So we call the attribute through it's base class -
            // ArgumentTransformationAttribute.
            var argTypeConverterAttr =
                psVariable.Attributes
                .OfType <ArgumentTransformationAttribute>()
                .FirstOrDefault(a => a.GetType().Name.Equals("ArgumentTypeConverterAttribute"));

            if (argTypeConverterAttr != null)
            {
                // PSVariable is strongly typed. Need to apply the conversion/transform to the new value.
                psCommand.Commands.Clear();
                psCommand = new PSCommand();
                psCommand.AddCommand(@"Microsoft.PowerShell.Utility\Get-Variable");
                psCommand.AddParameter("Name", "ExecutionContext");
                psCommand.AddParameter("ValueOnly");

                errorMessages.Clear();

                var getExecContextResults =
                    await this.powerShellContext.ExecuteCommandAsync <object>(
                        psCommand,
                        errorMessages,
                        sendErrorToHost : false).ConfigureAwait(false);

                EngineIntrinsics executionContext = getExecContextResults.OfType <EngineIntrinsics>().FirstOrDefault();

                var msg = $"Setting variable '{name}' using conversion to value: {psobject ?? "<null>"}";
                this.logger.LogTrace(msg);

                psVariable.Value = argTypeConverterAttr.Transform(executionContext, psobject);
            }
            else
            {
                // PSVariable is *not* strongly typed. In this case, whack the old value with the new value.
                var msg = $"Setting variable '{name}' directly to value: {psobject ?? "<null>"} - previous type was {psVariable.Value?.GetType().Name ?? "<unknown>"}";
                this.logger.LogTrace(msg);
                psVariable.Value = psobject;
            }

            // Use the VariableDetails.ValueString functionality to get the string representation for client debugger.
            // This makes the returned string consistent with the strings normally displayed for variables in the debugger.
            var tempVariable = new VariableDetails(psVariable);

            this.logger.LogTrace($"Set variable '{name}' to: {tempVariable.ValueString ?? "<null>"}");
            return(tempVariable.ValueString);
        }
Esempio n. 12
0
        public object GetVariableValue(string guid, string variableName)
        {
            var sessionExists = ScriptSessionManager.SessionExists(guid);

            if (sessionExists)
            {
                var session = ScriptSessionManager.GetSession(guid);
                try
                {
                    variableName = variableName.TrimStart('$');
                    var debugVariable = session.GetDebugVariable(variableName);
                    if (debugVariable == null)
                    {
                        return($"<div class='undefinedVariableType'>undefined</div>" +
                               $"<div class='variableLine'><span class='varName'>${variableName}</span> : <span class='varValue'>$null</span></div>");
                    }

                    var defaultProps = new List <string>();
                    if (debugVariable is PSObject && !session.IsRunning)
                    {
                        var script =
                            $"${variableName}.PSStandardMembers.DefaultDisplayPropertySet.ReferencedPropertyNames";
                        List <object> results;
                        if (session.TryInvokeInRunningSession(script, out results) && results != null)
                        {
                            defaultProps = results.Cast <string>().ToList();
                        }
                    }
                    var variable = debugVariable.BaseObject();
                    if (variable is PSCustomObject)
                    {
                        variable = debugVariable;
                    }
                    VariableDetails details  = new VariableDetails("$" + variableName, variable);
                    var             varValue = $"<div class='variableType'>{variable.GetType().FullName}</div>";
                    varValue +=
                        $"<div class='variableLine'><span class='varName'>${variableName}</span> : <span class='varValue'>{details.HtmlEncodedValueString}</span></div>";
                    if (details.IsExpandable)
                    {
                        foreach (var child in details.GetChildren().OrderBy(d => d.Name))
                        {
                            if (!child.IsExpandable ||
                                defaultProps.Contains(child.Name, StringComparer.OrdinalIgnoreCase) ||
                                ImportantProperties.Contains(child.Name, StringComparer.OrdinalIgnoreCase))
                            {
                                varValue +=
                                    $"<span class='varChild'><span class='childName'>{child.Name}</span> : <span class='childValue'>{child.HtmlEncodedValueString}</span></span>";
                            }
                            else
                            {
                                if (details.ShowDotNetProperties)
                                {
                                    continue;
                                }
                                varValue +=
                                    $"<span class='varChild'><span class='childName'>{child.Name}</span> : <span class='childValue'>{{";
                                foreach (var subChild in child.GetChildren())
                                {
                                    if (!subChild.IsExpandable)
                                    {
                                        varValue +=
                                            $"<span class='childName'>{subChild.Name}</span> : {subChild.HtmlEncodedValueString}, ";
                                    }
                                }
                                varValue  = varValue.TrimEnd(' ', ',');
                                varValue += "}</span></span>";
                            }
                        }
                    }
                    //var varValue = variable + " - "+ variable.GetType();
                    return(varValue);
                }
                catch (Exception ex)
                {
                    return(ex.Message);
                }
            }
            return($"<div class='undefinedVariableType'>Session not found</div>" +
                   $"<div class='variableLine'>A script needs to be executed in the session<br/>before the variable value can be inspected.</div>");
        }