/// <summary> /// Type initializer. Initialize the engine experimental feature list. /// </summary> static ExperimentalFeature() { // Initialize the readonly collection 'EngineExperimentalFeatures'. var engineFeatures = new ExperimentalFeature[] { /* Register engine experimental features here. Follow the same pattern as the example: * new ExperimentalFeature( * name: "PSFileSystemProviderV2", * description: "Replace the old FileSystemProvider with cleaner design and faster code"), */ new ExperimentalFeature( name: "PSCommandNotFoundSuggestion", description: "Recommend potential commands based on fuzzy search on a CommandNotFoundException"), new ExperimentalFeature( name: "PSNativePSPathResolution", description: "Convert PSPath to filesystem path, if possible, for native commands"), new ExperimentalFeature( name: "PSSubsystemPluginModel", description: "A plugin model for registering and un-registering PowerShell subsystems"), new ExperimentalFeature( name: PSNativeCommandArgumentPassingFeatureName, description: "Use ArgumentList when invoking a native command"), new ExperimentalFeature( name: "PSLoadAssemblyFromNativeCode", description: "Expose an API to allow assembly loading from native code"), new ExperimentalFeature( name: "PSAnsiRenderingFileInfo", description: "Enable coloring for FileInfo objects"), }; EngineExperimentalFeatures = new ReadOnlyCollection <ExperimentalFeature>(engineFeatures); // Initialize the readonly dictionary 'EngineExperimentalFeatureMap'. var engineExpFeatureMap = engineFeatures.ToDictionary(static f => f.Name, StringComparer.OrdinalIgnoreCase);
/// <summary> /// Type initializer. Initialize the engine experimental feature list. /// </summary> static ExperimentalFeature() { // Initialize the readonly collection 'EngineExperimentalFeatures'. var engineFeatures = new ExperimentalFeature[] { /* Register engine experimental features here. Follow the same pattern as the example: * new ExperimentalFeature( * name: "PSFileSystemProviderV2", * description: "Replace the old FileSystemProvider with cleaner design and faster code"), */ new ExperimentalFeature( name: "PSImplicitRemotingBatching", description: "Batch implicit remoting proxy commands to improve performance"), new ExperimentalFeature( name: "PSCommandNotFoundSuggestion", description: "Recommend potential commands based on fuzzy search on a CommandNotFoundException"), new ExperimentalFeature( name: "PSForEachObjectParallel", description: "New parameter set for ForEach-Object to run script blocks in parallel"), new ExperimentalFeature( name: "PSTernaryOperator", description: "Support the ternary operator in PowerShell language"), new ExperimentalFeature( name: "PSErrorView", description: "New formatting for ErrorRecord"), new ExperimentalFeature( name: "PSUpdatesNotification", description: "Print notification message when new releases are available"), new ExperimentalFeature( name: "PSCoalescingOperators", description: "Support the null coalescing operator and null coalescing assignment operator in PowerShell language"), new ExperimentalFeature( name: "PSPipelineChainOperators", description: "Allow use of && and || as operators between pipeline invocations"), }; EngineExperimentalFeatures = new ReadOnlyCollection <ExperimentalFeature>(engineFeatures); // Initialize the readonly dictionary 'EngineExperimentalFeatureMap'. var engineExpFeatureMap = engineFeatures.ToDictionary(f => f.Name, StringComparer.OrdinalIgnoreCase); EngineExperimentalFeatureMap = new ReadOnlyDictionary <string, ExperimentalFeature>(engineExpFeatureMap); // Initialize the readonly hashset 'EnabledExperimentalFeatureNames'. // The initialization of 'EnabledExperimentalFeatureNames' is deliberately made in the type initializer so that: // 1. 'EnabledExperimentalFeatureNames' can be declared as readonly; // 2. No need to deal with initialization from multiple threads; // 3. We don't need to decide where/when to read the config file for the enabled experimental features, // instead, it will be done when the type is used for the first time, which is always earlier than // any experimental features take effect. string[] enabledFeatures = Array.Empty <string>(); try { enabledFeatures = PowerShellConfig.Instance.GetExperimentalFeatures(); } catch (Exception e) when(LogException(e)) { } EnabledExperimentalFeatureNames = ProcessEnabledFeatures(enabledFeatures); }
/// <summary> /// Type initializer. Initialize the engine experimental feature list. /// </summary> static ExperimentalFeature() { // Initialize the readonly collection 'EngineExperimentalFeatures'. var engineFeatures = new ExperimentalFeature[] { /* Register engine experimental features here. Follow the same pattern as the example: * new ExperimentalFeature( * name: "PSFileSystemProviderV2", * description: "Replace the old FileSystemProvider with cleaner design and faster code"), */ new ExperimentalFeature( name: "PSImplicitRemotingBatching", description: "Batch implicit remoting proxy commands to improve performance"), new ExperimentalFeature( name: "PSCommandNotFoundSuggestion", description: "Recommend potential commands based on fuzzy search on a CommandNotFoundException"), #if UNIX new ExperimentalFeature( name: "PSUnixFileStat", description: "Provide unix permission information for files and directories"), #endif new ExperimentalFeature( name: "PSNullConditionalOperators", description: "Support the null conditional member access operators in PowerShell language"), new ExperimentalFeature( name: "PSCultureInvariantReplaceOperator", description: "Use culture invariant to-string convertor for lval in replace operator"), new ExperimentalFeature( name: "PSNativePSPathResolution", description: "Convert PSPath to filesystem path, if possible, for native commands"), new ExperimentalFeature( name: "PSNotApplyErrorActionToStderr", description: "Don't have $ErrorActionPreference affect stderr output"), }; EngineExperimentalFeatures = new ReadOnlyCollection <ExperimentalFeature>(engineFeatures); // Initialize the readonly dictionary 'EngineExperimentalFeatureMap'. var engineExpFeatureMap = engineFeatures.ToDictionary(f => f.Name, StringComparer.OrdinalIgnoreCase); EngineExperimentalFeatureMap = new ReadOnlyDictionary <string, ExperimentalFeature>(engineExpFeatureMap); // Initialize the readonly hashset 'EnabledExperimentalFeatureNames'. // The initialization of 'EnabledExperimentalFeatureNames' is deliberately made in the type initializer so that: // 1. 'EnabledExperimentalFeatureNames' can be declared as readonly; // 2. No need to deal with initialization from multiple threads; // 3. We don't need to decide where/when to read the config file for the enabled experimental features, // instead, it will be done when the type is used for the first time, which is always earlier than // any experimental features take effect. string[] enabledFeatures = Array.Empty <string>(); try { enabledFeatures = PowerShellConfig.Instance.GetExperimentalFeatures(); } catch (Exception e) when(LogException(e)) { } EnabledExperimentalFeatureNames = ProcessEnabledFeatures(enabledFeatures); }
/// <summary> /// Check if string is prefixed by psdrive, if so, expand it if filesystem path. /// </summary> /// <param name="path">The potential PSPath to resolve.</param> /// <param name="context">The current ExecutionContext.</param> /// <returns>Resolved PSPath if applicable otherwise the original path</returns> internal static string ResolvePath(string path, ExecutionContext context) { if (ExperimentalFeature.IsEnabled("PSNativePSPathResolution")) { #if !UNIX // on Windows, we need to expand ~ to point to user's home path if (string.Equals(path, "~", StringComparison.Ordinal) || path.StartsWith(TildeDirectorySeparator, StringComparison.Ordinal) || path.StartsWith(TildeAltDirectorySeparator, StringComparison.Ordinal)) { try { ProviderInfo fileSystemProvider = context.EngineSessionState.GetSingleProvider(FileSystemProvider.ProviderName); return(new StringBuilder(fileSystemProvider.Home) .Append(path.Substring(1)) .Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar) .ToString()); } catch { return(path); } } // check if the driveName is an actual disk drive on Windows, if so, no expansion if (path.Length >= 2 && path[1] == ':') { foreach (var drive in DriveInfo.GetDrives()) { if (drive.Name.StartsWith(new string(path[0], 1), StringComparison.OrdinalIgnoreCase)) { return(path); } } } #endif if (path.Contains(':')) { LocationGlobber globber = new LocationGlobber(context.SessionState); try { ProviderInfo providerInfo; // replace the argument with resolved path if it's a filesystem path string pspath = globber.GetProviderPath(path, out providerInfo); if (string.Equals(providerInfo.Name, FileSystemProvider.ProviderName, StringComparison.OrdinalIgnoreCase)) { path = pspath; } } catch { // if it's not a provider path, do nothing } } } return(path); }
/// <summary> /// Type initializer. Initialize the engine experimental feature list. /// </summary> static ExperimentalFeature() { // Initialize the readonly collection 'EngineExperimentalFeatures'. var engineFeatures = new ExperimentalFeature[] { /* Register engine experimental features here. Follow the same pattern as the example: * new ExperimentalFeature( * name: "PSFileSystemProviderV2", * description: "Replace the old FileSystemProvider with cleaner design and faster code", * source: EngineSource, * isEnabled: false), */ new ExperimentalFeature( name: "PSImplicitRemotingBatching", description: "Batch implicit remoting proxy commands to improve performance", source: EngineSource, isEnabled: false), new ExperimentalFeature( name: "PSUseAbbreviationExpansion", description: "Allow tab completion of cmdlets and functions by abbreviation", source: EngineSource, isEnabled: false), new ExperimentalFeature( name: "PSTempDrive", description: "Create TEMP: PS Drive mapped to user's temporary directory path", source: EngineSource, isEnabled: false), }; EngineExperimentalFeatures = new ReadOnlyCollection <ExperimentalFeature>(engineFeatures); // Initialize the readonly dictionary 'EngineExperimentalFeatureMap'. var engineExpFeatureMap = engineFeatures.ToDictionary(f => f.Name, StringComparer.OrdinalIgnoreCase); EngineExperimentalFeatureMap = new ReadOnlyDictionary <string, ExperimentalFeature>(engineExpFeatureMap); // Initialize the readonly hashset 'EnabledExperimentalFeatureNames'. // The initialization of 'EnabledExperimentalFeatureNames' is deliberately made in the type initializer so that: // 1. 'EnabledExperimentalFeatureNames' can be declared as readonly; // 2. No need to deal with initialization from multiple threads; // 3. We don't need to decide where/when to read the config file for the enabled experimental features, // instead, it will be done when the type is used for the first time, which is always earlier than // any experimental features take effect. string[] enabledFeatures = Utils.EmptyArray <string>(); try { enabledFeatures = PowerShellConfig.Instance.GetExperimentalFeatures(); } catch (Exception e) when(LogException(e)) { } EnabledExperimentalFeatureNames = ProcessEnabledFeatures(enabledFeatures); }
/// <summary> /// Type initializer. Initialize the engine experimental feature list. /// </summary> static ExperimentalFeature() { // Initialize the readonly collection 'EngineExperimentalFeatures'. var engineFeatures = new ExperimentalFeature[] { /* Register engine experimental features here. Follow the same pattern as the example: * new ExperimentalFeature( * name: "PSFileSystemProviderV2", * description: "Replace the old FileSystemProvider with cleaner design and faster code"), */ new ExperimentalFeature( name: "PSImplicitRemotingBatching", description: "Batch implicit remoting proxy commands to improve performance"), new ExperimentalFeature( name: "PSCommandNotFoundSuggestion", description: "Recommend potential commands based on fuzzy search on a CommandNotFoundException"), #if UNIX new ExperimentalFeature( name: "PSUnixFileStat", description: "Provide unix permission information for files and directories"), #endif new ExperimentalFeature( name: "PSCultureInvariantReplaceOperator", description: "Use culture invariant to-string convertor for lval in replace operator"), new ExperimentalFeature( name: "PSNativePSPathResolution", description: "Convert PSPath to filesystem path, if possible, for native commands"), new ExperimentalFeature( name: "PSNotApplyErrorActionToStderr", description: "Don't have $ErrorActionPreference affect stderr output"), new ExperimentalFeature( name: "PSSubsystemPluginModel", description: "A plugin model for registering and un-registering PowerShell subsystems"), new ExperimentalFeature( name: "PSAnsiRendering", description: "Enable $PSStyle variable to control ANSI rendering of strings"), new ExperimentalFeature( name: PSAnsiProgressFeatureName, description: "Enable lightweight progress bar that leverages ANSI codes for rendering"), new ExperimentalFeature( name: PSNativeCommandArgumentPassingFeatureName, description: "Use ArgumentList when invoking a native command"), new ExperimentalFeature( name: "PSLoadAssemblyFromNativeCode", description: "Expose an API to allow assembly loading from native code"), new ExperimentalFeature( name: "PSAnsiRenderingFileInfo", description: "Enable coloring for FileInfo objects"), }; EngineExperimentalFeatures = new ReadOnlyCollection <ExperimentalFeature>(engineFeatures); // Initialize the readonly dictionary 'EngineExperimentalFeatureMap'. var engineExpFeatureMap = engineFeatures.ToDictionary(static f => f.Name, StringComparer.OrdinalIgnoreCase);
/// <summary> /// Type initializer. Initialize the engine experimental feature list. /// </summary> static ExperimentalFeature() { // Initialize the readonly collection 'EngineExperimentalFeatures'. var engineFeatures = new ExperimentalFeature[] { /* Register engine experimental features here. Follow the same pattern as the example: * new ExperimentalFeature( * name: "PSFileSystemProviderV2", * description: "Replace the old FileSystemProvider with cleaner design and faster code"), */ new ExperimentalFeature( name: "PSCommandNotFoundSuggestion", description: "Recommend potential commands based on fuzzy search on a CommandNotFoundException"), new ExperimentalFeature( name: "PSNativePSPathResolution", description: "Convert PSPath to filesystem path, if possible, for native commands"), new ExperimentalFeature( name: "PSSubsystemPluginModel", description: "A plugin model for registering and un-registering PowerShell subsystems"), new ExperimentalFeature( name: PSNativeCommandArgumentPassingFeatureName, description: "Use ArgumentList when invoking a native command"), new ExperimentalFeature( name: "PSLoadAssemblyFromNativeCode", description: "Expose an API to allow assembly loading from native code"), new ExperimentalFeature( name: "PSAnsiRenderingFileInfo", description: "Enable coloring for FileInfo objects"), new ExperimentalFeature( name: PSNativeCommandErrorActionPreferenceFeatureName, description: "Native commands with non-zero exit codes issue errors according to $ErrorActionPreference when $PSNativeCommandUseErrorActionPreference is $true"), new ExperimentalFeature( name: PSRemotingSSHTransportErrorHandling, description: "Removes the SSH remoting transport stdErr stream message handling as terminating errors, and instead just writes error messages to console."), new ExperimentalFeature( name: PSCleanBlockFeatureName, description: "Add support of a 'Clean' block to functions and script cmdlets for easy resource cleanup"), new ExperimentalFeature( name: PSAMSIMethodInvocationLogging, description: "Provides AMSI notification of .NET method invocations."), new ExperimentalFeature( name: PSExecFeatureName, description: "Add 'exec' built-in command on Linux and macOS"), new ExperimentalFeature( name: PSStrictModeAssignment, description: "Add support of setting Strict-Mode with Invoke-Command"), }; EngineExperimentalFeatures = new ReadOnlyCollection <ExperimentalFeature>(engineFeatures); // Initialize the readonly dictionary 'EngineExperimentalFeatureMap'. var engineExpFeatureMap = engineFeatures.ToDictionary(static f => f.Name, StringComparer.OrdinalIgnoreCase);
private static List <Hashtable> InitializeSuggestions() { var suggestions = new List <Hashtable>( new Hashtable[] { NewSuggestion( id: 1, category: "Transactions", matchType: SuggestionMatchType.Command, rule: "^Start-Transaction", suggestion: SuggestionStrings.Suggestion_StartTransaction, enabled: true), NewSuggestion( id: 2, category: "Transactions", matchType: SuggestionMatchType.Command, rule: "^Use-Transaction", suggestion: SuggestionStrings.Suggestion_UseTransaction, enabled: true), NewSuggestion( id: 3, category: "General", matchType: SuggestionMatchType.Dynamic, rule: ScriptBlock.CreateDelayParsedScriptBlock(s_checkForCommandInCurrentDirectoryScript, isProductCode: true), suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_createCommandExistsInCurrentDirectoryScript, isProductCode: true), suggestionArgs: new object[] { CodeGeneration.EscapeSingleQuotedStringContent(SuggestionStrings.Suggestion_CommandExistsInCurrentDirectory) }, enabled: true) }); if (ExperimentalFeature.IsEnabled("PSCommandNotFoundSuggestion")) { suggestions.Add( NewSuggestion( id: 4, category: "General", matchType: SuggestionMatchType.ErrorId, rule: "CommandNotFoundException", suggestion: ScriptBlock.CreateDelayParsedScriptBlock(s_getFuzzyMatchedCommands, isProductCode: true), suggestionArgs: new object[] { CodeGeneration.EscapeSingleQuotedStringContent(SuggestionStrings.Suggestion_CommandNotFound) }, enabled: true)); } return(suggestions); }
/// <summary> /// Type initializer. Initialize the engine experimental feature list. /// </summary> static ExperimentalFeature() { // Initialize the readonly collection 'EngineExperimentalFeatures'. var engineFeatures = new ExperimentalFeature[] { /* Register engine experimental features here. Follow the same pattern as the example: * new ExperimentalFeature( * name: "PSFileSystemProviderV2", * description: "Replace the old FileSystemProvider with cleaner design and faster code"), */ new ExperimentalFeature( name: "PSImplicitRemotingBatching", description: "Batch implicit remoting proxy commands to improve performance"), new ExperimentalFeature( name: "PSCommandNotFoundSuggestion", description: "Recommend potential commands based on fuzzy search on a CommandNotFoundException"), }; EngineExperimentalFeatures = new ReadOnlyCollection <ExperimentalFeature>(engineFeatures); // Initialize the readonly dictionary 'EngineExperimentalFeatureMap'. var engineExpFeatureMap = engineFeatures.ToDictionary(f => f.Name, StringComparer.OrdinalIgnoreCase); EngineExperimentalFeatureMap = new ReadOnlyDictionary <string, ExperimentalFeature>(engineExpFeatureMap); // Initialize the readonly hashset 'EnabledExperimentalFeatureNames'. // The initialization of 'EnabledExperimentalFeatureNames' is deliberately made in the type initializer so that: // 1. 'EnabledExperimentalFeatureNames' can be declared as readonly; // 2. No need to deal with initialization from multiple threads; // 3. We don't need to decide where/when to read the config file for the enabled experimental features, // instead, it will be done when the type is used for the first time, which is always earlier than // any experimental features take effect. string[] enabledFeatures = Array.Empty <string>(); try { enabledFeatures = PowerShellConfig.Instance.GetExperimentalFeatures(); } catch (Exception e) when(LogException(e)) { } EnabledExperimentalFeatureNames = ProcessEnabledFeatures(enabledFeatures); }
internal void BindParameters(Collection <CommandParameterInternal> parameters) { bool sawVerbatimArgumentMarker = false; bool first = true; foreach (CommandParameterInternal parameter in parameters) { if (!first) { _arguments.Append(' '); } first = false; if (parameter.ParameterNameSpecified) { Diagnostics.Assert(!parameter.ParameterText.Contains(' '), "Parameters cannot have whitespace"); PossiblyGlobArg(parameter.ParameterText, parameter, StringConstantType.BareWord); if (parameter.SpaceAfterParameter) { _arguments.Append(' '); } } if (parameter.ArgumentSpecified) { // If this is the verbatim argument marker, we don't pass it on to the native command. // We do need to remember it though - we'll expand environment variables in subsequent args. object argValue = parameter.ArgumentValue; if (string.Equals("--%", argValue as string, StringComparison.OrdinalIgnoreCase)) { sawVerbatimArgumentMarker = true; continue; } if (argValue != AutomationNull.Value && argValue != UnboundParameter.Value) { // ArrayLiteralAst is used to reconstruct the correct argument, e.g. // windbg -k com:port=\\devbox\pipe\debug,pipe,resets=0,reconnect // The parser produced an array of strings but marked the parameter so we // can properly reconstruct the correct command line. StringConstantType stringConstantType = StringConstantType.BareWord; ArrayLiteralAst arrayLiteralAst = null; switch (parameter?.ArgumentAst) { case StringConstantExpressionAst sce: stringConstantType = sce.StringConstantType; break; case ExpandableStringExpressionAst ese: stringConstantType = ese.StringConstantType; break; case ArrayLiteralAst ala: arrayLiteralAst = ala; break; } // Prior to PSNativePSPathResolution experimental feature, a single quote worked the same as a double quote // so if the feature is not enabled, we treat any quotes as double quotes. When this feature is no longer // experimental, this code here needs to be removed. if (!ExperimentalFeature.IsEnabled("PSNativePSPathResolution") && stringConstantType == StringConstantType.SingleQuoted) { stringConstantType = StringConstantType.DoubleQuoted; } AppendOneNativeArgument(Context, parameter, argValue, arrayLiteralAst, sawVerbatimArgumentMarker, stringConstantType); } } } }