private void RunClause(Action <FunctionContext> clause, object dollarUnderbar, object inputToProcess) { ExecutionContext.CheckStackDepth(); _anyClauseExecuted = true; Pipe oldErrorOutputPipe = this.Context.ShellFunctionErrorOutputPipe; // If the script block has a different language mode than the current, // change the language mode. PSLanguageMode?oldLanguageMode = null; PSLanguageMode?newLanguageMode = null; if ((_scriptBlock.LanguageMode.HasValue) && (_scriptBlock.LanguageMode != Context.LanguageMode)) { oldLanguageMode = Context.LanguageMode; newLanguageMode = _scriptBlock.LanguageMode; } try { var oldScopeOrigin = this.Context.EngineSessionState.CurrentScope.ScopeOrigin; try { this.Context.EngineSessionState.CurrentScope.ScopeOrigin = this._dontUseScopeCommandOrigin ? CommandOrigin.Internal : this.Command.CommandOrigin; // Set the language mode. We do this before EnterScope(), so that the language // mode is appropriately applied for evaluation parameter defaults. if (newLanguageMode.HasValue) { Context.LanguageMode = newLanguageMode.Value; } bool?oldLangModeTransitionStatus = null; try { // If it's from ConstrainedLanguage to FullLanguage, indicate the transition before parameter binding takes place. if (oldLanguageMode == PSLanguageMode.ConstrainedLanguage && newLanguageMode == PSLanguageMode.FullLanguage) { oldLangModeTransitionStatus = Context.LanguageModeTransitionInParameterBinding; Context.LanguageModeTransitionInParameterBinding = true; } EnterScope(); } finally { if (oldLangModeTransitionStatus.HasValue) { // Revert the transition state to old value after doing the parameter binding Context.LanguageModeTransitionInParameterBinding = oldLangModeTransitionStatus.Value; } } if (commandRuntime.ErrorMergeTo == MshCommandRuntime.MergeDataStream.Output) { Context.RedirectErrorPipe(commandRuntime.OutputPipe); } else if (commandRuntime.ErrorOutputPipe.IsRedirected) { Context.RedirectErrorPipe(commandRuntime.ErrorOutputPipe); } if (dollarUnderbar != AutomationNull.Value) { _localsTuple.SetAutomaticVariable(AutomaticVariable.Underbar, dollarUnderbar, _context); } else if (_dollarUnderbar != AutomationNull.Value) { _localsTuple.SetAutomaticVariable(AutomaticVariable.Underbar, _dollarUnderbar, _context); } if (inputToProcess != AutomationNull.Value) { if (inputToProcess == null) { inputToProcess = MshCommandRuntime.StaticEmptyArray.GetEnumerator(); } else { IList list = inputToProcess as IList; inputToProcess = (list != null) ? list.GetEnumerator() : LanguagePrimitives.GetEnumerator(inputToProcess); } _localsTuple.SetAutomaticVariable(AutomaticVariable.Input, inputToProcess, _context); } clause(_functionContext); } catch (TargetInvocationException tie) { // DynamicInvoke wraps exceptions, unwrap them here. throw tie.InnerException; } finally { Context.ShellFunctionErrorOutputPipe = oldErrorOutputPipe; if (oldLanguageMode.HasValue) { Context.LanguageMode = oldLanguageMode.Value; } Context.EngineSessionState.CurrentScope.ScopeOrigin = oldScopeOrigin; } } catch (ExitException ee) { if (!this.FromScriptFile || _rethrowExitException) { throw; } this._exitWasCalled = true; int exitCode = (int)ee.Argument; this.Command.Context.SetVariable(SpecialVariables.LastExitCodeVarPath, exitCode); if (exitCode != 0) { this.commandRuntime.PipelineProcessor.ExecutionFailed = true; } } catch (FlowControlException) { throw; } catch (RuntimeException e) { // This method always throws. ManageScriptException(e); } catch (Exception e) { // This cmdlet threw an exception, so wrap it and bubble it up. throw ManageInvocationException(e); } }
internal static Uri GetUriFromCommandPSObject(PSObject commandFullHelp) { // this object knows Maml format... // So retrieve Uri information as per the format.. if ((commandFullHelp is null) || (commandFullHelp.Properties["relatedLinks"] is null) || (commandFullHelp.Properties["relatedLinks"].Value is null)) { // return the default.. return(null); } PSObject relatedLinks = PSObject.AsPSObject(commandFullHelp.Properties["relatedLinks"].Value); if (relatedLinks.Properties["navigationLink"] is null) { return(null); } object[] navigationLinks = (object[])LanguagePrimitives.ConvertTo( relatedLinks.Properties["navigationLink"].Value, typeof(object[]), CultureInfo.InvariantCulture); foreach (object navigationLinkAsObject in navigationLinks) { if (navigationLinkAsObject is null) { continue; } PSObject navigationLink = PSObject.AsPSObject(navigationLinkAsObject); PSNoteProperty uriNP = navigationLink.Properties["uri"] as PSNoteProperty; if (uriNP != null) { string uriString = string.Empty; LanguagePrimitives.TryConvertTo <string>(uriNP.Value, CultureInfo.InvariantCulture, out uriString); if (!string.IsNullOrEmpty(uriString)) { if (!System.Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute)) { // WinBlue: 545315 Online help links are broken with localized help // Example: https://go.microsoft.com/fwlink/?LinkID=113324 (moglicherwei se auf Englisch) // Split the string based on <s> (space). We decided to go with this approach as // UX localization authors use spaces. Correctly extracting only the wellformed URI // is out-of-scope for this fix. string[] tempUriSplitArray = uriString.Split(Utils.Separators.Space); uriString = tempUriSplitArray[0]; } try { return(new System.Uri(uriString)); // return only the first Uri (ignore other uris) } catch (UriFormatException) { throw PSTraceSource.NewInvalidOperationException(HelpErrors.InvalidURI, uriString); } } } } return(null); }
private void ConvertCommand(CommandAst commandAst, bool isTrustedInput) { // First need command name. var commandName = GetCommandName(commandAst.CommandElements[0], isTrustedInput); var command = new Command(commandName, isScript: false, useLocalScope: _createLocalScope); // Handle redirections, if any (there can really be just 0 or 1). if (commandAst.Redirections.Count > 0) { Diagnostics.Assert(commandAst.Redirections.Count == 1, "only 1 kind of redirection is supported"); Diagnostics.Assert(commandAst.Redirections[0] is MergingRedirectionAst, "unexpected redirection type"); PipelineResultTypes toType = PipelineResultTypes.Output; PipelineResultTypes fromType; switch (commandAst.Redirections[0].FromStream) { case RedirectionStream.Error: fromType = PipelineResultTypes.Error; break; case RedirectionStream.Warning: fromType = PipelineResultTypes.Warning; break; case RedirectionStream.Verbose: fromType = PipelineResultTypes.Verbose; break; case RedirectionStream.Debug: fromType = PipelineResultTypes.Debug; break; case RedirectionStream.Information: fromType = PipelineResultTypes.Information; break; case RedirectionStream.All: fromType = PipelineResultTypes.All; break; default: // Default to Error->Output to be compatible with V2. fromType = PipelineResultTypes.Error; break; } command.MergeMyResults(fromType, toType); } _powershell.AddCommand(command); // Now the parameters and arguments. foreach (var ast in commandAst.CommandElements.Skip(1)) { var exprAst = ast as ExpressionAst; if (exprAst != null) { VariableExpressionAst variableAst = null; var usingExprAst = ast as UsingExpressionAst; if (usingExprAst != null) { string usingAstKey = PsUtils.GetUsingExpressionKey(usingExprAst); object usingValue = _usingValueMap[usingAstKey]; variableAst = usingExprAst.SubExpression as VariableExpressionAst; if (variableAst != null && variableAst.Splatted) { // Support the splatting of a dictionary var parameters = usingValue as System.Collections.IDictionary; if (parameters != null) { _powershell.AddParameters(parameters); } else { // Support the splatting of an array var arguments = usingValue as System.Collections.IEnumerable; if (arguments != null) { foreach (object argument in arguments) { _powershell.AddArgument(argument); } } else { // Splat the object directly. _powershell.AddArgument(usingValue); } } } else { _powershell.AddArgument(usingValue); } continue; } variableAst = ast as VariableExpressionAst; if (variableAst != null && variableAst.Splatted) { GetSplattedVariable(variableAst); } else { var constantExprAst = ast as ConstantExpressionAst; object argument; if (constantExprAst != null && (LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constantExprAst.StaticType)) || constantExprAst.StaticType == typeof(System.Numerics.BigInteger))) { var commandArgumentText = constantExprAst.Extent.Text; argument = constantExprAst.Value; if (!commandArgumentText.Equals(constantExprAst.Value.ToString(), StringComparison.Ordinal)) { // The wrapped number will actually return a PSObject which could end holding a reference to // a typetable, making the object runspace specific. We should find a better way to avoid // any possibility of sharing problems, though this is unlikely to cause problems. argument = ParserOps.WrappedNumber(argument, commandArgumentText); } } else { if (!isTrustedInput) { try { argument = GetSafeValueVisitor.GetSafeValue(exprAst, _context, GetSafeValueVisitor.SafeValueContext.GetPowerShell); } catch (System.Exception) { throw new ScriptBlockToPowerShellNotSupportedException( "CantConvertWithDynamicExpression", null, AutomationExceptions.CantConvertWithDynamicExpression, exprAst.Extent.Text); } } else { argument = GetExpressionValue(exprAst, isTrustedInput); } } _powershell.AddArgument(argument); } } else { AddParameter((CommandParameterAst)ast, isTrustedInput); } } }
/// <summary> /// Read the 'Zone.Identifier' alternate data stream to determin SecurityZone of the file. /// </summary> private static SecurityZone ReadFromZoneIdentifierDataStream(string filePath) { try { FileStream zoneDataSteam = AlternateDataStreamUtilities.CreateFileStream( filePath, "Zone.Identifier", FileMode.Open, FileAccess.Read, FileShare.Read); // If we successfully get the zone data stream, try to read the ZoneId information using (StreamReader zoneDataReader = new StreamReader(zoneDataSteam, GetDefaultEncoding())) { string line = null; bool zoneTransferMatched = false; // After a lot experiments with Zone.CreateFromUrl/Zone.SecurityZone, the way it handles the alternate // data stream 'Zone.Identifier' is observed as follows: // 1. Read content of the data stream line by line. Each line is trimmed. // 2. Try to match the current line with '^\[ZoneTransfer\]'. // - if matching, then do step #3 starting from the next line // - if not matching, then continue to do step #2 with the next line. // 3. Try to match the current line with '^ZoneId\s*=\s*(.*)' // - if matching, check if the ZoneId is valid. Then return the corresponding SecurityZone if valid, or 'NoZone' if invalid. // - if not matching, then continue to do step #3 with the next line. // 4. Reach EOF, then return 'NoZone'. while ((line = zoneDataReader.ReadLine()) != null) { line = line.Trim(); if (!zoneTransferMatched) { zoneTransferMatched = Regex.IsMatch(line, @"^\[ZoneTransfer\]", RegexOptions.IgnoreCase); } else { Match match = Regex.Match(line, @"^ZoneId\s*=\s*(.*)", RegexOptions.IgnoreCase); if (!match.Success) { continue; } // Match found. Validate ZoneId value. string zoneIdRawValue = match.Groups[1].Value; match = Regex.Match(zoneIdRawValue, @"^[+-]?\d+", RegexOptions.IgnoreCase); if (!match.Success) { return(SecurityZone.NoZone); } string zoneId = match.Groups[0].Value; SecurityZone result; return(LanguagePrimitives.TryConvertTo(zoneId, out result) ? result : SecurityZone.NoZone); } } } } catch (FileNotFoundException) { // FileNotFoundException may be thrown by AlternateDataStreamUtilities.CreateFileStream when the data stream 'Zone.Identifier' // does not exist, or when the underlying file system doesn't support alternate data stream. } return(SecurityZone.NoZone); }
private Collection <PSObject> InvokeScript(ScriptBlock sb, bool useNewScope, PipelineResultTypes writeToPipeline, IList input, params object[] args) { if (_cmdlet != null) { _cmdlet.ThrowIfStopping(); } Cmdlet cmdletToUse = null; ScriptBlock.ErrorHandlingBehavior errorHandlingBehavior = ScriptBlock.ErrorHandlingBehavior.WriteToExternalErrorPipe; // Check if they want output if ((writeToPipeline & PipelineResultTypes.Output) == PipelineResultTypes.Output) { cmdletToUse = _cmdlet; writeToPipeline &= (~PipelineResultTypes.Output); } // Check if they want error if ((writeToPipeline & PipelineResultTypes.Error) == PipelineResultTypes.Error) { errorHandlingBehavior = ScriptBlock.ErrorHandlingBehavior.WriteToCurrentErrorPipe; writeToPipeline &= (~PipelineResultTypes.Error); } if (writeToPipeline != PipelineResultTypes.None) { // The only output types are Output and Error. throw PSTraceSource.NewNotImplementedException(); } // If the cmdletToUse is not null, then the result of the evaluation will be // streamed out the output pipe of the cmdlet. object rawResult; if (cmdletToUse != null) { sb.InvokeUsingCmdlet( contextCmdlet: cmdletToUse, useLocalScope: useNewScope, errorHandlingBehavior: errorHandlingBehavior, dollarUnder: AutomationNull.Value, input: input, scriptThis: AutomationNull.Value, args: args); rawResult = AutomationNull.Value; } else { rawResult = sb.DoInvokeReturnAsIs( useLocalScope: useNewScope, errorHandlingBehavior: errorHandlingBehavior, dollarUnder: AutomationNull.Value, input: input, scriptThis: AutomationNull.Value, args: args); } if (rawResult == AutomationNull.Value) { return(new Collection <PSObject>()); } // If the result is already a collection of PSObjects, just return it... Collection <PSObject> result = rawResult as Collection <PSObject>; if (result != null) { return(result); } result = new Collection <PSObject>(); IEnumerator list = null; list = LanguagePrimitives.GetEnumerator(rawResult); if (list != null) { while (list.MoveNext()) { object val = list.Current; result.Add(LanguagePrimitives.AsPSObjectOrNull(val)); } } else { result.Add(LanguagePrimitives.AsPSObjectOrNull(rawResult)); } return(result); }
internal static object GetMDArrayValueOrSlice(Array array, object indexes) { Exception whyFailed = null; int[] indexArray = null; try { indexArray = (int[])LanguagePrimitives.ConvertTo(indexes, typeof(int[]), NumberFormatInfo.InvariantInfo); } catch (InvalidCastException ice) { // Ignore an exception here as we may actually be looking at an array of arrays // which could still be ok. Save the exception as we may use it later... whyFailed = ice; } if (indexArray != null) { if (indexArray.Length != array.Rank) { // rank failed to match so error... ReportIndexingError(array, indexes, null); } return(GetMDArrayValue(array, indexArray, false)); } var indexList = new List <int[]>(); var ie = LanguagePrimitives.GetEnumerator(indexes); while (EnumerableOps.MoveNext(null, ie)) { var currentIndex = EnumerableOps.Current(ie); try { indexArray = LanguagePrimitives.ConvertTo <int[]>(currentIndex); } catch (InvalidCastException) { indexArray = null; } if (indexArray == null || indexArray.Length != array.Rank) { if (whyFailed != null) { // If the first fails, report the original exception and all indices ReportIndexingError(array, indexes, whyFailed); Diagnostics.Assert(false, "ReportIndexingError must throw"); } // If the second or subsequent index fails, report the failure for just that index ReportIndexingError(array, currentIndex, null); Diagnostics.Assert(false, "ReportIndexingError must throw"); } // Only use whyFailed the first time through, otherwise whyFailed = null; indexList.Add(indexArray); } // Optimistically assume all indices are valid so the result array is the same size. // If that turns out to be wrong, we'll just copy the elements produced. var result = new object[indexList.Count]; int j = 0; foreach (var i in indexList) { var value = GetMDArrayValue(array, i, true); if (value != AutomationNull.Value) { result[j++] = value; } } if (j != indexList.Count) { var shortResult = new object[j]; Array.Copy(result, shortResult, j); return(shortResult); } return(result); }
internal static bool IsNumeric(this Type type) { return(LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(type))); }
internal static bool IsNumericOrPrimitive(this Type type) { return(type.GetTypeInfo().IsPrimitive || LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(type))); }
internal static bool IsFloating(this Type type) { return(LanguagePrimitives.IsFloating(LanguagePrimitives.GetTypeCode(type))); }
internal static object GetMDArrayValueOrSlice(Array array, object indexes) { Exception reason = null; int[] numArray = null; try { numArray = (int[])LanguagePrimitives.ConvertTo(indexes, typeof(int[]), NumberFormatInfo.InvariantInfo); } catch (InvalidCastException exception2) { reason = exception2; } if (numArray != null) { if (numArray.Length != array.Rank) { ReportIndexingError(array, indexes, null); } return(GetMDArrayValue(array, numArray, false)); } List <int[]> list = new List <int[]>(); IEnumerator enumerator = LanguagePrimitives.GetEnumerator(indexes); while (EnumerableOps.MoveNext(null, enumerator)) { object valueToConvert = EnumerableOps.Current(enumerator); try { numArray = LanguagePrimitives.ConvertTo <int[]>(valueToConvert); } catch (InvalidCastException) { numArray = null; } if ((numArray == null) || (numArray.Length != array.Rank)) { if (reason != null) { ReportIndexingError(array, indexes, reason); } ReportIndexingError(array, valueToConvert, null); } reason = null; list.Add(numArray); } object[] sourceArray = new object[list.Count]; int length = 0; foreach (int[] numArray2 in list) { object obj3 = GetMDArrayValue(array, numArray2, true); if (obj3 != AutomationNull.Value) { sourceArray[length++] = obj3; } } if (length != list.Count) { object[] destinationArray = new object[length]; Array.Copy(sourceArray, destinationArray, length); return(destinationArray); } return(sourceArray); }
/// <summary> /// Evaluate a given flag enum value against the expression. /// </summary> /// <param name="value"> /// The flag enum value to be evaluated. /// </param> /// <returns> /// Whether the enum value satisfy the expression. /// </returns> public bool Evaluate(T value) { object val = LanguagePrimitives.ConvertTo(value, _underType, CultureInfo.InvariantCulture); return(Root.Eval(val)); }
/// <summary> /// Stringize a non-IEnum argument to a native command, adding quotes /// and trailing spaces as appropriate. An array gets added as multiple arguments /// each of which will be stringized. /// </summary> /// <param name="context">Execution context instance.</param> /// <param name="parameter">The parameter associated with the operation.</param> /// <param name="obj">The object to append.</param> /// <param name="argArrayAst">If the argument was an array literal, the Ast, otherwise null.</param> /// <param name="sawVerbatimArgumentMarker">True if the argument occurs after --%.</param> /// <param name="stringConstantType">Bare, SingleQuoted, or DoubleQuoted.</param> private void AppendOneNativeArgument(ExecutionContext context, CommandParameterInternal parameter, object obj, ArrayLiteralAst argArrayAst, bool sawVerbatimArgumentMarker, StringConstantType stringConstantType) { IEnumerator list = LanguagePrimitives.GetEnumerator(obj); Diagnostics.Assert((argArrayAst == null) || (obj is object[] && ((object[])obj).Length == argArrayAst.Elements.Count), "array argument and ArrayLiteralAst differ in number of elements"); int currentElement = -1; string separator = string.Empty; do { string arg; object currentObj; if (list == null) { arg = PSObject.ToStringParser(context, obj); currentObj = obj; } else { if (!ParserOps.MoveNext(context, null, list)) { break; } currentObj = ParserOps.Current(null, list); arg = PSObject.ToStringParser(context, currentObj); currentElement += 1; if (currentElement != 0) { separator = GetEnumerableArgSeparator(argArrayAst, currentElement); } } if (!string.IsNullOrEmpty(arg)) { // Only add the separator to the argument string rather than adding a separator to the ArgumentList. _arguments.Append(separator); if (sawVerbatimArgumentMarker) { arg = Environment.ExpandEnvironmentVariables(arg); _arguments.Append(arg); // we need to split the argument on spaces _argumentList.AddRange(arg.Split(' ', StringSplitOptions.RemoveEmptyEntries)); } else { // We need to add quotes if the argument has unquoted spaces. The // quotes could appear anywhere inside the string, not just at the start, // e.g. // $a = 'a"b c"d' // echoargs $a 'a"b c"d' a"b c"d // // The above should see 3 identical arguments in argv (the command line will // actually have quotes in different places, but the Win32 command line=>argv parser // erases those differences. // // We need to check quotes that the win32 argument parser checks which is currently // just the normal double quotes, no other special quotes. Also note that mismatched // quotes are supported if (NeedQuotes(arg)) { _arguments.Append('"'); if (stringConstantType == StringConstantType.DoubleQuoted) { _arguments.Append(ResolvePath(arg, Context)); AddToArgumentList(parameter, ResolvePath(arg, Context)); } else { _arguments.Append(arg); AddToArgumentList(parameter, arg); } // need to escape all trailing backslashes so the native command receives it correctly // according to http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESDOC for (int i = arg.Length - 1; i >= 0 && arg[i] == '\\'; i--) { _arguments.Append('\\'); } _arguments.Append('"'); } else { if (argArrayAst != null && ArgumentPassingStyle == NativeArgumentPassingStyle.Standard) { // We have a literal array, so take the extent, break it on spaces and add them to the argument list. foreach (string element in argArrayAst.Extent.Text.Split(' ', StringSplitOptions.RemoveEmptyEntries)) { PossiblyGlobArg(element, parameter, stringConstantType); } break; } else { PossiblyGlobArg(arg, parameter, stringConstantType); } } } } else if (ArgumentPassingStyle == NativeArgumentPassingStyle.Standard && currentObj != null) { // add empty strings to arglist, but not nulls AddToArgumentList(parameter, arg); } }while (list != null); }
internal static ArrayList GetSuggestion(HistoryInfo lastHistory, Object lastError, ArrayList errorList) { ArrayList returnSuggestions = new ArrayList(); PSModuleInfo invocationModule = new PSModuleInfo(true); invocationModule.SessionState.PSVariable.Set("lastHistory", lastHistory); invocationModule.SessionState.PSVariable.Set("lastError", lastError); int initialErrorCount = 0; // Go through all of the suggestions foreach (Hashtable suggestion in s_suggestions) { initialErrorCount = errorList.Count; // Make sure the rule is enabled if (!LanguagePrimitives.IsTrue(suggestion["Enabled"])) { continue; } SuggestionMatchType matchType = (SuggestionMatchType)LanguagePrimitives.ConvertTo( suggestion["MatchType"], typeof(SuggestionMatchType), CultureInfo.InvariantCulture); // If this is a dynamic match, evaluate the ScriptBlock if (matchType == SuggestionMatchType.Dynamic) { object result = null; ScriptBlock evaluator = suggestion["Rule"] as ScriptBlock; if (evaluator == null) { suggestion["Enabled"] = false; throw new ArgumentException( SuggestionStrings.RuleMustBeScriptBlock, "Rule"); } try { result = invocationModule.Invoke(evaluator, null); } catch (Exception) { // Catch-all OK. This is a third-party call-out. suggestion["Enabled"] = false; continue; } // If it returned results, evaluate its suggestion if (LanguagePrimitives.IsTrue(result)) { string suggestionText = GetSuggestionText(suggestion["Suggestion"], (object[])suggestion["SuggestionArgs"], invocationModule); if (!String.IsNullOrEmpty(suggestionText)) { string returnString = String.Format( CultureInfo.CurrentCulture, "Suggestion [{0},{1}]: {2}", (int)suggestion["Id"], (string)suggestion["Category"], suggestionText); returnSuggestions.Add(returnString); } } } else { string matchText = String.Empty; // Otherwise, this is a Regex match against the // command or error if (matchType == SuggestionMatchType.Command) { matchText = lastHistory.CommandLine; } else if (matchType == SuggestionMatchType.Error) { if (lastError != null) { Exception lastException = lastError as Exception; if (lastException != null) { matchText = lastException.Message; } else { matchText = lastError.ToString(); } } } else { suggestion["Enabled"] = false; throw new ArgumentException( SuggestionStrings.InvalidMatchType, "MatchType"); } // If the text matches, evaluate the suggestion if (Regex.IsMatch(matchText, (string)suggestion["Rule"], RegexOptions.IgnoreCase)) { string suggestionText = GetSuggestionText(suggestion["Suggestion"], (object[])suggestion["SuggestionArgs"], invocationModule); if (!String.IsNullOrEmpty(suggestionText)) { string returnString = String.Format( CultureInfo.CurrentCulture, "Suggestion [{0},{1}]: {2}", (int)suggestion["Id"], (string)suggestion["Category"], suggestionText); returnSuggestions.Add(returnString); } } } // If the rule generated an error, disable it if (errorList.Count != initialErrorCount) { suggestion["Enabled"] = false; } } return(returnSuggestions); }
/// <summary> /// Sets the value of a property coming from a previous call to GetMember /// </summary> /// <param name="property">PSProperty coming from a previous call to GetMember</param> /// <param name="setValue">value to set the property with</param> /// <param name="convertIfPossible">instructs the adapter to convert before setting, if the adapter supports conversion</param> protected override void PropertySet(PSProperty property, object setValue, bool convertIfPossible) { PropertyValueCollection values = property.adapterData as PropertyValueCollection; if (null != values) { // This means GetMember returned PropertyValueCollection try { values.Clear(); } catch (System.Runtime.InteropServices.COMException e) { if (e.ErrorCode != unchecked ((int)0x80004005) || (setValue == null)) { // When clear is called, DirectoryEntry calls PutEx on AD object with Clear option and Null Value // WinNT provider throws E_FAIL when null value is specified though actually ADS_PROPERTY_CLEAR option is used, // we need to catch this exception here. // But at the same time we don't want to catch the exception if user explicitly sets the value to null. throw; } } IEnumerable enumValues = LanguagePrimitives.GetEnumerable(setValue); if (enumValues == null) { values.Add(setValue); } else { foreach (object objValue in enumValues) { values.Add(objValue); } } } else { // This means GetMember returned the value from InvokeGet..So set the value using InvokeSet. DirectoryEntry entry = (DirectoryEntry)property.baseObject; Diagnostics.Assert(entry != null, "Object should be of type DirectoryEntry in DirectoryEntry adapter."); List <object> setValues = new List <object>(); IEnumerable enumValues = LanguagePrimitives.GetEnumerable(setValue); if (enumValues == null) { setValues.Add(setValue); } else { foreach (object objValue in enumValues) { setValues.Add(objValue); } } entry.InvokeSet(property.name, setValues.ToArray()); } return; }
/// <summary> /// Override - Modify Parameters element in maml1 using the Parameters element from maml2. /// This will copy parameters from maml2 that are not present in maml1. /// </summary> internal static void OverrideParameters(PSObject maml1, PSObject maml2) { string[] parametersPath = new string[] { "Parameters", "Parameter" }; // Final collection of PSObjects. List <object> maml2items = new List <object>(); // Add maml2 first since we are prepending. // For maml2: Add as collection or single item. No-op if PSPropertyInfo propertyInfo2 = GetPropertyInfo(maml2, parametersPath); var array = propertyInfo2.Value as Array; if (array != null) { maml2items.AddRange(array as IEnumerable <object>); } else { maml2items.Add(PSObject.AsPSObject(propertyInfo2.Value)); } // Extend maml1 to make sure the property-path exists - since we'll be modifying it soon. EnsurePropertyInfoPathExists(maml1, parametersPath); // For maml1: Add as collection or single item. Do nothing if null or some other type. PSPropertyInfo propertyInfo1 = GetPropertyInfo(maml1, parametersPath); List <object> maml1items = new List <object>(); array = propertyInfo1.Value as Array; if (array != null) { maml1items.AddRange(array as IEnumerable <object>); } else { maml1items.Add(PSObject.AsPSObject(propertyInfo1.Value)); } // copy parameters from maml2 that are not present in maml1 for (int index = 0; index < maml2items.Count; index++) { PSObject m2paramObj = PSObject.AsPSObject(maml2items[index]); string param2Name = ""; PSPropertyInfo m2propertyInfo = m2paramObj.Properties["Name"]; if (null != m2propertyInfo) { if (!LanguagePrimitives.TryConvertTo <string>(m2propertyInfo.Value, out param2Name)) { continue; } } bool isParamFoundInMaml1 = false; foreach (PSObject m1ParamObj in maml1items) { string param1Name = ""; PSPropertyInfo m1PropertyInfo = m1ParamObj.Properties["Name"]; if (null != m1PropertyInfo) { if (!LanguagePrimitives.TryConvertTo <string>(m1PropertyInfo.Value, out param1Name)) { continue; } } if (param1Name.Equals(param2Name, StringComparison.OrdinalIgnoreCase)) { isParamFoundInMaml1 = true; } } if (!isParamFoundInMaml1) { maml1items.Add(maml2items[index]); } } // Now replace in maml1. If items.Count == 0 do nothing since Value is already null. if (maml1items.Count == 1) { propertyInfo1.Value = maml1items[0]; } else if (maml1items.Count >= 2) { propertyInfo1.Value = maml1items.ToArray(); } }
internal static bool IsInteger(this Type type) { return(LanguagePrimitives.IsInteger(LanguagePrimitives.GetTypeCode(type))); }
internal Uri LookupUriFromCommandInfo() { CommandTypes cmdTypesToLookFor = CommandTypes.Cmdlet; switch (this.HelpCategory) { case Automation.HelpCategory.Cmdlet: cmdTypesToLookFor = CommandTypes.Cmdlet; break; case Automation.HelpCategory.Function: cmdTypesToLookFor = CommandTypes.Function; break; case Automation.HelpCategory.ScriptCommand: cmdTypesToLookFor = CommandTypes.Script; break; case Automation.HelpCategory.ExternalScript: cmdTypesToLookFor = CommandTypes.ExternalScript; break; case Automation.HelpCategory.Filter: cmdTypesToLookFor = CommandTypes.Filter; break; case Automation.HelpCategory.Configuration: cmdTypesToLookFor = CommandTypes.Configuration; break; default: return(null); } string commandName = this.Name; string moduleName = string.Empty; if (this.FullHelp.Properties["ModuleName"] != null) { PSNoteProperty moduleNameNP = this.FullHelp.Properties["ModuleName"] as PSNoteProperty; if (moduleNameNP != null) { LanguagePrimitives.TryConvertTo <string>(moduleNameNP.Value, CultureInfo.InvariantCulture, out moduleName); } } string commandToSearch = commandName; if (!string.IsNullOrEmpty(moduleName)) { commandToSearch = string.Format(CultureInfo.InvariantCulture, "{0}\\{1}", moduleName, commandName); } ExecutionContext context = LocalPipeline.GetExecutionContextFromTLS(); if (context == null) { return(null); } try { CommandInfo cmdInfo = null; if (cmdTypesToLookFor == CommandTypes.Cmdlet) { cmdInfo = context.SessionState.InvokeCommand.GetCmdlet(commandToSearch); } else { cmdInfo = context.SessionState.InvokeCommand.GetCommands(commandToSearch, cmdTypesToLookFor, false).FirstOrDefault(); } if ((cmdInfo == null) || (cmdInfo.CommandMetadata == null)) { return(null); } string uriString = cmdInfo.CommandMetadata.HelpUri; if (!string.IsNullOrEmpty(uriString)) { if (!System.Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute)) { // WinBlue: 545315 Online help links are broken with localized help // Example: https://go.microsoft.com/fwlink/?LinkID=113324 (moglicherwei se auf Englisch) // Split the string based on <s> (space). We decided to go with this approach as // UX localization authors use spaces. Correctly extracting only the wellformed URI // is out-of-scope for this fix. string[] tempUriSplitArray = uriString.Split(Utils.Separators.Space); uriString = tempUriSplitArray[0]; } try { return(new System.Uri(uriString)); // return only the first Uri (ignore other uris) } catch (UriFormatException) { throw PSTraceSource.NewInvalidOperationException(HelpErrors.InvalidURI, cmdInfo.CommandMetadata.HelpUri); } } } catch (CommandNotFoundException) { } return(null); }
/// <summary> /// Stringize a non-IEnum argument to a native command, adding quotes /// and trailing spaces as appropriate. An array gets added as multiple arguments /// each of which will be stringized. /// </summary> /// <param name="context">Execution context instance</param> /// <param name="obj">The object to append</param> /// <param name="argArrayAst">If the argument was an array literal, the Ast, otherwise null</param> /// <param name="sawVerbatimArgumentMarker">true if the argument occurs after --%</param> /// <param name="usedQuotes">True if the argument was a quoted string (single or double)</param> private void appendOneNativeArgument(ExecutionContext context, object obj, ArrayLiteralAst argArrayAst, bool sawVerbatimArgumentMarker, bool usedQuotes) { IEnumerator list = LanguagePrimitives.GetEnumerator(obj); Diagnostics.Assert(argArrayAst == null || obj is object[] && ((object[])obj).Length == argArrayAst.Elements.Count, "array argument and ArrayLiteralAst differ in number of elements"); int currentElement = -1; string separator = ""; do { string arg; if (list == null) { arg = PSObject.ToStringParser(context, obj); } else { if (!ParserOps.MoveNext(context, null, list)) { break; } arg = PSObject.ToStringParser(context, ParserOps.Current(null, list)); currentElement += 1; if (currentElement != 0) { separator = GetEnumerableArgSeparator(argArrayAst, currentElement); } } if (!String.IsNullOrEmpty(arg)) { _arguments.Append(separator); if (sawVerbatimArgumentMarker) { arg = Environment.ExpandEnvironmentVariables(arg); _arguments.Append(arg); } else { // We need to add quotes if the argument has unquoted spaces. The // quotes could appear anywhere inside the string, not just at the start, // e.g. // $a = 'a"b c"d' // echoargs $a 'a"b c"d' a"b c"d // // The above should see 3 identical arguments in argv (the command line will // actually have quotes in different places, but the Win32 command line=>argv parser // erases those differences. // // We need to check quotes that the win32 argument parser checks which is currently // just the normal double quotes, no other special quotes. Also note that mismatched // quotes are supported if (NeedQuotes(arg)) { _arguments.Append('"'); // need to escape all trailing backslashes so the native command receives it correctly // according to http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESDOC _arguments.Append(arg); for (int i = arg.Length - 1; i >= 0 && arg[i] == '\\'; i--) { _arguments.Append('\\'); } _arguments.Append('"'); } else { PossiblyGlobArg(arg, usedQuotes); } } } } while (list != null); }