First round of workflow cleanup (#4777)
This round of cleanup focuses on the following areas - Tab completion code - InitialSessionState - Compiler/MiscOps - Utils/SessionStateFunctionAPIs Changes in the rest affected files are mainly some corresponding changes due to the cleanup work in the above areas.
This commit is contained in:
parent
b2fa0ee522
commit
db33d90479
|
@ -1407,9 +1407,8 @@ namespace System.Management.Automation
|
|||
StringLiterals.PowerShellModuleFileExtension,
|
||||
StringLiterals.PowerShellDataFileExtension,
|
||||
StringLiterals.PowerShellNgenAssemblyExtension,
|
||||
StringLiterals.DependentWorkflowAssemblyExtension,
|
||||
StringLiterals.PowerShellCmdletizationFileExtension,
|
||||
StringLiterals.WorkflowFileExtension
|
||||
StringLiterals.PowerShellILAssemblyExtension,
|
||||
StringLiterals.PowerShellCmdletizationFileExtension
|
||||
};
|
||||
result = CompletionCompleters.CompleteFilename(completionContext, false, moduleExtensions).ToList();
|
||||
if (completionContext.WordToComplete.IndexOfAny(Utils.Separators.DirectoryOrDrive) != -1)
|
||||
|
|
|
@ -118,13 +118,6 @@ namespace System.Management.Automation
|
|||
Exception exceptionThrown;
|
||||
var commandInfos = context.Helper.ExecuteCurrentPowerShell(out exceptionThrown);
|
||||
|
||||
// Complete against pseudo commands that work only in the script workflow.
|
||||
// If RelatedAst is null then it's for argument completion, because we don't complete pseudo commands for arguments
|
||||
if (lastAst != null)
|
||||
{
|
||||
commandInfos = CompleteWorkflowCommand(commandName, lastAst, commandInfos);
|
||||
}
|
||||
|
||||
if (commandInfos != null && commandInfos.Count > 1)
|
||||
{
|
||||
// OrderBy is using stable sorting
|
||||
|
@ -197,21 +190,6 @@ namespace System.Management.Automation
|
|||
return commandResults;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new instance of CompletionContext with RelatedAst = null.
|
||||
/// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
/// The way to avoid that is to pass in a CompletionContext with RelatedAst = null.
|
||||
/// </summary>
|
||||
private static CompletionContext NewContextToCompleteCommandAsArgument(CompletionContext context)
|
||||
{
|
||||
return new CompletionContext {
|
||||
WordToComplete = context.WordToComplete,
|
||||
Helper = context.Helper,
|
||||
ExecutionContext = context.ExecutionContext,
|
||||
Options = context.Options
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly HashSet<string> s_keywordsToExcludeFromAddingAmpersand
|
||||
= new HashSet<string>(StringComparer.OrdinalIgnoreCase) { TokenKind.InlineScript.ToString(), TokenKind.Configuration.ToString() };
|
||||
internal static CompletionResult GetCommandNameCompletionResult(string name, object command, bool addAmpersandIfNecessary, string quote)
|
||||
|
@ -364,9 +342,7 @@ namespace System.Management.Automation
|
|||
for (int index = 1; index < commandList.Count; index++)
|
||||
{
|
||||
var commandInfo = commandList[index] as CommandInfo;
|
||||
// If it's a pseudo command that only works in the script workflow, don't bother adding it to the result
|
||||
// list since it's a duplicate
|
||||
if (commandInfo == null) { continue; }
|
||||
Diagnostics.Assert(commandInfo != null, "Elements should always be CommandInfo");
|
||||
|
||||
if (commandInfo.CommandType == CommandTypes.Application)
|
||||
{
|
||||
|
@ -409,30 +385,6 @@ namespace System.Management.Automation
|
|||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the pseudo commands that only work in the script workflow.
|
||||
/// </summary>
|
||||
internal static readonly List<string> PseudoWorkflowCommands
|
||||
= new List<string> { "Checkpoint-Workflow", "Suspend-Workflow", "InlineScript" };
|
||||
private static Collection<PSObject> CompleteWorkflowCommand(string command, Ast lastAst, Collection<PSObject> commandInfos)
|
||||
{
|
||||
if (!lastAst.IsInWorkflow())
|
||||
return commandInfos;
|
||||
|
||||
commandInfos = commandInfos ?? new Collection<PSObject>();
|
||||
var commandPattern = WildcardPattern.Get(command, WildcardOptions.IgnoreCase);
|
||||
|
||||
foreach (string pseudoCommand in PseudoWorkflowCommands)
|
||||
{
|
||||
if (!commandPattern.IsMatch(pseudoCommand))
|
||||
continue;
|
||||
|
||||
commandInfos.Add(PSObject.AsPSObject(pseudoCommand));
|
||||
}
|
||||
|
||||
return commandInfos;
|
||||
}
|
||||
|
||||
private class FindFunctionsVisitor : AstVisitor
|
||||
{
|
||||
internal readonly List<FunctionDefinitionAst> FunctionDefinitions = new List<FunctionDefinitionAst>();
|
||||
|
@ -1339,10 +1291,7 @@ namespace System.Management.Automation
|
|||
|
||||
if (context.WordToComplete != string.Empty && context.WordToComplete.IndexOf('-') != -1)
|
||||
{
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext);
|
||||
var commandResults = CompleteCommand(context);
|
||||
if (commandResults != null)
|
||||
result.AddRange(commandResults);
|
||||
}
|
||||
|
@ -2103,10 +2052,7 @@ namespace System.Management.Automation
|
|||
{
|
||||
if (parameterName.Equals("Command", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext);
|
||||
var commandResults = CompleteCommand(context);
|
||||
if (commandResults != null)
|
||||
result.AddRange(commandResults);
|
||||
}
|
||||
|
@ -2796,10 +2742,7 @@ namespace System.Management.Automation
|
|||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
// Available commands
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext, moduleName);
|
||||
var commandResults = CompleteCommand(context, moduleName);
|
||||
if (commandResults != null)
|
||||
result.AddRange(commandResults);
|
||||
|
||||
|
@ -2858,11 +2801,8 @@ namespace System.Management.Automation
|
|||
RemoveLastNullCompletionResult(result);
|
||||
|
||||
// Available commands
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
const CommandTypes commandTypes = CommandTypes.Cmdlet | CommandTypes.Function | CommandTypes.Alias | CommandTypes.ExternalScript | CommandTypes.Workflow | CommandTypes.Configuration;
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext, /* moduleName: */ null, commandTypes);
|
||||
const CommandTypes commandTypes = CommandTypes.Cmdlet | CommandTypes.Function | CommandTypes.Alias | CommandTypes.ExternalScript | CommandTypes.Configuration;
|
||||
var commandResults = CompleteCommand(context, /* moduleName: */ null, commandTypes);
|
||||
if (commandResults != null)
|
||||
result.AddRange(commandResults);
|
||||
|
||||
|
@ -3113,9 +3053,8 @@ namespace System.Management.Automation
|
|||
StringLiterals.PowerShellModuleFileExtension,
|
||||
StringLiterals.PowerShellDataFileExtension,
|
||||
StringLiterals.PowerShellNgenAssemblyExtension,
|
||||
StringLiterals.DependentWorkflowAssemblyExtension,
|
||||
StringLiterals.PowerShellCmdletizationFileExtension,
|
||||
StringLiterals.WorkflowFileExtension
|
||||
StringLiterals.PowerShellILAssemblyExtension,
|
||||
StringLiterals.PowerShellCmdletizationFileExtension
|
||||
};
|
||||
var moduleFilesResults = new List<CompletionResult>(CompleteFilename(context, /* containerOnly: */ false, moduleExtensions));
|
||||
if (moduleFilesResults.Count > 0)
|
||||
|
@ -3514,11 +3453,8 @@ namespace System.Management.Automation
|
|||
{
|
||||
// Complete for the parameter Definition
|
||||
// Available commands
|
||||
// For argument completion, we don't want to complete against pseudo commands that only work in the script workflow.
|
||||
// The way to avoid that is to pass in a CompletionContext with RelatedAst = null
|
||||
const CommandTypes commandTypes = CommandTypes.Cmdlet | CommandTypes.Function | CommandTypes.ExternalScript | CommandTypes.Workflow | CommandTypes.Configuration;
|
||||
var newContext = NewContextToCompleteCommandAsArgument(context);
|
||||
var commandResults = CompleteCommand(newContext, /* moduleName: */ null, commandTypes);
|
||||
const CommandTypes commandTypes = CommandTypes.Cmdlet | CommandTypes.Function | CommandTypes.ExternalScript | CommandTypes.Configuration;
|
||||
var commandResults = CompleteCommand(context, /* moduleName: */ null, commandTypes);
|
||||
if (commandResults != null && commandResults.Count > 0)
|
||||
result.AddRange(commandResults);
|
||||
|
||||
|
|
|
@ -1137,18 +1137,11 @@ namespace System.Management.Automation.Language
|
|||
private Collection<AstParameterArgumentPair> _duplicateParameters;
|
||||
private Dictionary<CommandParameterAst, ParameterBindingException> _bindingExceptions;
|
||||
|
||||
// A corresponding list is also kept in WorkflowJobConverter.cs.
|
||||
private List<string> _ignoredWorkflowParameters = null;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize collection/dictionary members when it's necessary
|
||||
/// </summary>
|
||||
private void InitializeMembers()
|
||||
{
|
||||
List<string> supportedCommonParameters = new List<string>() { "Verbose", "Debug", "ErrorAction", "WarningAction", "InformationAction" };
|
||||
_ignoredWorkflowParameters = new List<string>(Cmdlet.CommonParameters.Concat<string>(Cmdlet.OptionalCommonParameters));
|
||||
_ignoredWorkflowParameters.RemoveAll(item => supportedCommonParameters.Contains(item, StringComparer.OrdinalIgnoreCase));
|
||||
|
||||
// Initializing binding related members
|
||||
_function = false;
|
||||
_commandName = null;
|
||||
|
@ -1193,7 +1186,6 @@ namespace System.Management.Automation.Language
|
|||
|
||||
CommandProcessorBase processor = null;
|
||||
string commandName = null;
|
||||
bool psuedoWorkflowCommand = false;
|
||||
try
|
||||
{
|
||||
processor = PrepareFromAst(context, out commandName) ?? context.CreateCommand(commandName, dotSource);
|
||||
|
@ -1201,16 +1193,7 @@ namespace System.Management.Automation.Language
|
|||
catch (RuntimeException)
|
||||
{
|
||||
// Failed to create the CommandProcessor;
|
||||
if (_commandAst.IsInWorkflow() &&
|
||||
commandName != null &&
|
||||
CompletionCompleters.PseudoWorkflowCommands.Contains(commandName, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
psuedoWorkflowCommand = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var commandProcessor = processor as CommandProcessor;
|
||||
|
@ -1221,7 +1204,7 @@ namespace System.Management.Automation.Language
|
|||
var argumentsToGetDynamicParameters = implementsDynamicParameters
|
||||
? new List<object>(_commandElements.Count)
|
||||
: null;
|
||||
if (commandProcessor != null || scriptProcessor != null || psuedoWorkflowCommand)
|
||||
if (commandProcessor != null || scriptProcessor != null)
|
||||
{
|
||||
// Pre-processing the arguments -- command arguments
|
||||
for (commandIndex++; commandIndex < _commandElements.Count; commandIndex++)
|
||||
|
@ -1326,89 +1309,12 @@ namespace System.Management.Automation.Language
|
|||
_bindableParameters = scriptProcessor.ScriptParameterBinderController.BindableParameters;
|
||||
_defaultParameterSetFlag = 0;
|
||||
}
|
||||
else if (!psuedoWorkflowCommand)
|
||||
else
|
||||
{
|
||||
// The command is not a function, cmdlet and script cmdlet
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_commandAst.IsInWorkflow())
|
||||
{
|
||||
var converterType = Type.GetType(Utils.WorkflowType);
|
||||
var activityParameters = (Dictionary<string, Type>) converterType?.GetMethod("GetActivityParameters").Invoke(null, new object[] { _commandAst });
|
||||
if (activityParameters != null)
|
||||
{
|
||||
bool needToRemoveReplacedProperty = activityParameters.ContainsKey("PSComputerName") &&
|
||||
!activityParameters.ContainsKey("ComputerName");
|
||||
|
||||
var parametersToAdd = new List<MergedCompiledCommandParameter>();
|
||||
var attrCollection = new Collection<Attribute> { new ParameterAttribute() };
|
||||
foreach (var pair in activityParameters)
|
||||
{
|
||||
if (psuedoWorkflowCommand || !_bindableParameters.BindableParameters.ContainsKey(pair.Key))
|
||||
{
|
||||
Type parameterType = GetActualActivityParameterType(pair.Value);
|
||||
var runtimeDefinedParameter = new RuntimeDefinedParameter(pair.Key, parameterType, attrCollection);
|
||||
var compiledCommandParameter = new CompiledCommandParameter(runtimeDefinedParameter, false) { IsInAllSets = true };
|
||||
var mergedCompiledCommandParameter = new MergedCompiledCommandParameter(compiledCommandParameter, ParameterBinderAssociation.DeclaredFormalParameters);
|
||||
parametersToAdd.Add(mergedCompiledCommandParameter);
|
||||
}
|
||||
}
|
||||
if (parametersToAdd.Any())
|
||||
{
|
||||
var mergedBindableParameters = new MergedCommandParameterMetadata();
|
||||
if (!psuedoWorkflowCommand)
|
||||
{
|
||||
mergedBindableParameters.ReplaceMetadata(_bindableParameters);
|
||||
}
|
||||
foreach (var p in parametersToAdd)
|
||||
{
|
||||
mergedBindableParameters.BindableParameters.Add(p.Parameter.Name, p);
|
||||
}
|
||||
_bindableParameters = mergedBindableParameters;
|
||||
}
|
||||
|
||||
// Remove common parameters that are supported by all commands, but not
|
||||
// by workflows
|
||||
bool fixedReadOnly = false;
|
||||
foreach (var ignored in _ignoredWorkflowParameters)
|
||||
{
|
||||
if (_bindableParameters.BindableParameters.ContainsKey(ignored))
|
||||
{
|
||||
// However, some ignored parameters are explicitly implemented by
|
||||
// activities, so keep them.
|
||||
if (!activityParameters.ContainsKey(ignored))
|
||||
{
|
||||
if (!fixedReadOnly)
|
||||
{
|
||||
_bindableParameters.ResetReadOnly();
|
||||
fixedReadOnly = true;
|
||||
}
|
||||
|
||||
_bindableParameters.BindableParameters.Remove(ignored);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_bindableParameters.BindableParameters.ContainsKey("ComputerName") && needToRemoveReplacedProperty)
|
||||
{
|
||||
if (!fixedReadOnly)
|
||||
{
|
||||
_bindableParameters.ResetReadOnly();
|
||||
fixedReadOnly = true;
|
||||
}
|
||||
|
||||
_bindableParameters.BindableParameters.Remove("ComputerName");
|
||||
string aliasOfComputerName = (from aliasPair in _bindableParameters.AliasedParameters
|
||||
where String.Equals("ComputerName", aliasPair.Value.Parameter.Name)
|
||||
select aliasPair.Key).FirstOrDefault();
|
||||
if (aliasOfComputerName != null)
|
||||
{
|
||||
_bindableParameters.AliasedParameters.Remove(aliasOfComputerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_unboundParameters.AddRange(_bindableParameters.BindableParameters.Values);
|
||||
|
||||
// Pre-processing the arguments -- pipeline input
|
||||
|
@ -1464,108 +1370,13 @@ namespace System.Management.Automation.Language
|
|||
FunctionDefinitionAst functionDefinitionAst;
|
||||
if (exportVisitor.DiscoveredFunctions.TryGetValue(resolvedCommandName, out functionDefinitionAst))
|
||||
{
|
||||
// We could use the IAstToScriptBlockConverter to get the actual script block, but that can be fairly expensive for workflows.
|
||||
// IAstToScriptBlockConverter is public, so we might consider converting non-workflows, but the interface isn't really designed
|
||||
// for Intellisense, so we can't really expect good performance, so instead we'll just fall back on the actual
|
||||
// parameters we see in the ast.
|
||||
var scriptBlock = functionDefinitionAst.IsWorkflow
|
||||
? CreateFakeScriptBlockForWorkflow(functionDefinitionAst)
|
||||
: new ScriptBlock(functionDefinitionAst, functionDefinitionAst.IsFilter);
|
||||
var scriptBlock = new ScriptBlock(functionDefinitionAst, functionDefinitionAst.IsFilter);
|
||||
commandProcessor = CommandDiscovery.CreateCommandProcessorForScript(scriptBlock, context, true, context.EngineSessionState);
|
||||
}
|
||||
|
||||
}
|
||||
return commandProcessor;
|
||||
}
|
||||
|
||||
private static ScriptBlock CreateFakeScriptBlockForWorkflow(FunctionDefinitionAst functionDefinitionAst)
|
||||
{
|
||||
// The common parameters for a workflow is are always the same, the only difference is what parameters
|
||||
// the workflow specifies. When we generate the wrapper, the users parameters are "tweaked" slightly,
|
||||
// but those differences shouldn't matter for Intellisense. They could for the syntax if we showed it,
|
||||
// but the differences are very minor. See ImportWorkflowCommand.AddCommonWfParameters in
|
||||
// admin\monad\src\m3p\product\ServiceCore\WorkflowCore\ImportWorkflowCommand.cs for the actual logic
|
||||
// that creates this string.
|
||||
|
||||
const string paramBlock = @"
|
||||
[CmdletBinding()]
|
||||
{0}
|
||||
param (
|
||||
{1}
|
||||
[hashtable[]] $PSParameterCollection,
|
||||
[string[]] $PSComputerName,
|
||||
[ValidateNotNullOrEmpty()] $PSCredential,
|
||||
[uint32] $PSConnectionRetryCount,
|
||||
[uint32] $PSConnectionRetryIntervalSec,
|
||||
[ValidateRange(1, 2147483)][uint32] $PSRunningTimeoutSec,
|
||||
[ValidateRange(1, 2147483)][uint32] $PSElapsedTimeoutSec,
|
||||
[bool] $PSPersist,
|
||||
[ValidateNotNullOrEmpty()] [System.Management.Automation.Runspaces.AuthenticationMechanism] $PSAuthentication,
|
||||
[ValidateNotNullOrEmpty()][System.Management.AuthenticationLevel] $PSAuthenticationLevel,
|
||||
[ValidateNotNullOrEmpty()] [string] $PSApplicationName,
|
||||
[uint32] $PSPort,
|
||||
[switch] $PSUseSSL,
|
||||
[ValidateNotNullOrEmpty()] [string] $PSConfigurationName,
|
||||
[ValidateNotNullOrEmpty()][string[]] $PSConnectionURI,
|
||||
[switch] $PSAllowRedirection,
|
||||
[ValidateNotNullOrEmpty()][System.Management.Automation.Remoting.PSSessionOption] $PSSessionOption,
|
||||
[ValidateNotNullOrEmpty()] [string] $PSCertificateThumbprint,
|
||||
[hashtable] $PSPrivateMetadata,
|
||||
[switch] $AsJob,
|
||||
[string] $JobName,
|
||||
[Parameter(ValueFromPipeline=$true)]$InputObject
|
||||
)
|
||||
";
|
||||
|
||||
var outputTypeText = new StringBuilder();
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var paramBlockAst = functionDefinitionAst.Body.ParamBlock;
|
||||
if (paramBlockAst != null)
|
||||
{
|
||||
var outputTypeAttrs = paramBlockAst.Attributes.Where(attribute => typeof(OutputTypeAttribute) == attribute.TypeName.GetReflectionAttributeType());
|
||||
|
||||
foreach (AttributeAst attributeAst in outputTypeAttrs)
|
||||
{
|
||||
outputTypeText.Append(attributeAst.Extent.Text);
|
||||
}
|
||||
}
|
||||
|
||||
var parameterAsts = ((IParameterMetadataProvider)functionDefinitionAst).Parameters;
|
||||
if (parameterAsts != null)
|
||||
{
|
||||
var first = true;
|
||||
foreach (var parameter in parameterAsts)
|
||||
{
|
||||
if (!first) sb.Append(", ");
|
||||
first = false;
|
||||
sb.Append(parameter.Extent.Text);
|
||||
}
|
||||
if (!first) sb.Append(", ");
|
||||
}
|
||||
|
||||
Token[] tokens;
|
||||
ParseError[] errors;
|
||||
var ast = Parser.ParseInput(string.Format(CultureInfo.InvariantCulture, paramBlock, outputTypeText.ToString(), sb.ToString()), out tokens, out errors);
|
||||
return ast.GetScriptBlock();
|
||||
}
|
||||
|
||||
private static Type GetActualActivityParameterType(Type parameterType)
|
||||
{
|
||||
if (parameterType.GetTypeInfo().IsGenericType)
|
||||
{
|
||||
var fullName = parameterType.GetGenericTypeDefinition().FullName;
|
||||
if (fullName.Equals("System.Activities.InArgument`1", StringComparison.Ordinal) ||
|
||||
fullName.Equals("System.Activities.InOutArgument`1", StringComparison.Ordinal))
|
||||
{
|
||||
parameterType = parameterType.GetGenericArguments()[0];
|
||||
}
|
||||
}
|
||||
parameterType = Nullable.GetUnderlyingType(parameterType) ?? parameterType;
|
||||
return parameterType;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parse the arguments to process switch parameters and parameters without a value
|
||||
/// specified. We always eat the error (such as parameter without value) and continue
|
||||
|
|
|
@ -225,7 +225,7 @@ namespace System.Management.Automation
|
|||
// Manifest module (.psd1)
|
||||
Module.SetVersion(ModuleIntrinsics.GetManifestModuleVersion(Module.Path));
|
||||
}
|
||||
else if (Module.Path.EndsWith(StringLiterals.DependentWorkflowAssemblyExtension, StringComparison.OrdinalIgnoreCase))
|
||||
else if (Module.Path.EndsWith(StringLiterals.PowerShellILAssemblyExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Binary module (.dll)
|
||||
Module.SetVersion(AssemblyName.GetAssemblyName(Module.Path).Version);
|
||||
|
|
|
@ -34,14 +34,6 @@ namespace System.Management.Automation
|
|||
/// </summary>
|
||||
RemoteServer = 0x1,
|
||||
|
||||
/// <summary>
|
||||
/// Session with <see cref="WorkflowServer"/> capabilities can be made available on
|
||||
/// a server that wants to provide workflow hosting capabilities in the
|
||||
/// specified end points. All jobs commands as well as commands for
|
||||
/// implicit remoting and interactive remoting will be made available
|
||||
/// </summary>
|
||||
WorkflowServer = 0x2,
|
||||
|
||||
/// <summary>
|
||||
/// Include language capabilities
|
||||
/// </summary>
|
||||
|
@ -1339,16 +1331,6 @@ end
|
|||
restrictedCommands.AddRange(GetRestrictedRemotingCommands());
|
||||
}
|
||||
|
||||
if (SessionCapabilities.WorkflowServer == (sessionCapabilities & SessionCapabilities.WorkflowServer))
|
||||
{
|
||||
#if CORECLR // Workflow Not Supported On PowerShell Core
|
||||
throw PSTraceSource.NewNotSupportedException(ParserStrings.WorkflowNotSupportedInPowerShellCore);
|
||||
#else
|
||||
restrictedCommands.AddRange(GetRestrictedRemotingCommands());
|
||||
restrictedCommands.AddRange(GetRestrictedJobCommands());
|
||||
#endif
|
||||
}
|
||||
|
||||
Dictionary<string, CommandMetadata> result = new Dictionary<string, CommandMetadata>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (CommandMetadata restrictedCommand in restrictedCommands)
|
||||
{
|
||||
|
|
|
@ -393,7 +393,6 @@ namespace System.Management.Automation
|
|||
|
||||
internal static List<string> ModulesWithJobSourceAdapters = new List<string>
|
||||
{
|
||||
Utils.WorkflowModule,
|
||||
Utils.ScheduledJobModuleName,
|
||||
};
|
||||
|
||||
|
|
|
@ -833,102 +833,6 @@ namespace System.Management.Automation.Runspaces
|
|||
public string HelpFile { get; private set; }
|
||||
}
|
||||
|
||||
#if !CORECLR // Workflow Not Supported On CSS
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed class SessionStateWorkflowEntry : SessionStateCommandEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a workflow definition in an Initial session state object.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the workflow</param>
|
||||
/// <param name="definition">The definition of the workflow</param>
|
||||
/// <param name="options">Options controlling scope-related elements of this object</param>
|
||||
/// <param name="helpFile">The name of the help file associated with the workflow</param>
|
||||
public SessionStateWorkflowEntry(string name, string definition, ScopedItemOptions options, string helpFile)
|
||||
: base(name, SessionStateEntryVisibility.Public)
|
||||
{
|
||||
Definition = definition;
|
||||
CommandType = CommandTypes.Workflow;
|
||||
Options = options;
|
||||
HelpFile = helpFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a workflow definition in an Initial session state object.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the workflow</param>
|
||||
/// <param name="definition">The definition of the workflow</param>
|
||||
/// <param name="helpFile">The name of the help file associated with the workflow</param>
|
||||
public SessionStateWorkflowEntry(string name, string definition, string helpFile)
|
||||
: this(name, definition, ScopedItemOptions.None, helpFile)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a workflow definition in an Initial session state object.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the workflow</param>
|
||||
/// <param name="definition">The definition of the workflow</param>
|
||||
public SessionStateWorkflowEntry(string name, string definition)
|
||||
: this(name, definition, ScopedItemOptions.None, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is an internal copy constructor.
|
||||
/// </summary>
|
||||
internal SessionStateWorkflowEntry(string name, string definition, ScopedItemOptions options, SessionStateEntryVisibility visibility, WorkflowInfo workflow, string helpFile)
|
||||
: base(name, visibility)
|
||||
{
|
||||
Definition = definition;
|
||||
Options = options;
|
||||
WorkflowInfo = workflow;
|
||||
HelpFile = helpFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shallow-clone this object...
|
||||
/// </summary>
|
||||
/// <returns>The cloned object</returns>
|
||||
public override InitialSessionStateEntry Clone()
|
||||
{
|
||||
SessionStateWorkflowEntry entry = new SessionStateWorkflowEntry(Name, Definition, Options, Visibility, WorkflowInfo, HelpFile);
|
||||
entry.SetModule(this.Module);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the name of the help file associated with the function.
|
||||
/// </summary>
|
||||
internal void SetHelpFile(string help)
|
||||
{
|
||||
HelpFile = help;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The string to use to define this function...
|
||||
/// </summary>
|
||||
public string Definition { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The script block for this function.
|
||||
/// </summary>
|
||||
internal WorkflowInfo WorkflowInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Options controling scope visibility and setability for this entry.
|
||||
/// </summary>
|
||||
public ScopedItemOptions Options { get; } = ScopedItemOptions.None;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the help file associated with the function.
|
||||
/// </summary>
|
||||
public string HelpFile { get; private set; }
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -1481,29 +1385,6 @@ namespace System.Management.Automation.Runspaces
|
|||
return CreateRestrictedForRemoteServer();
|
||||
}
|
||||
|
||||
#if CORECLR // Workflow Not Supported On CSS
|
||||
if ((sessionCapabilities & SessionCapabilities.WorkflowServer) == SessionCapabilities.WorkflowServer)
|
||||
{
|
||||
throw PSTraceSource.NewNotSupportedException(ParserStrings.WorkflowNotSupportedInPowerShellCore);
|
||||
}
|
||||
#else
|
||||
// only workflow has been requested
|
||||
if (SessionCapabilities.WorkflowServer == sessionCapabilities)
|
||||
{
|
||||
return CreateRestrictedForWorkflowServerMinimum();
|
||||
}
|
||||
|
||||
// workflow server with remoting support has been requested
|
||||
if (sessionCapabilities == (SessionCapabilities.WorkflowServer | SessionCapabilities.RemoteServer))
|
||||
{
|
||||
return CreateRestrictedForWorkflowServer();
|
||||
}
|
||||
|
||||
if (sessionCapabilities == (SessionCapabilities.WorkflowServer | SessionCapabilities.RemoteServer | SessionCapabilities.Language))
|
||||
{
|
||||
return CreateRestrictedForWorkflowServerWithFullLanguage();
|
||||
}
|
||||
#endif
|
||||
return Create();
|
||||
}
|
||||
|
||||
|
@ -1610,296 +1491,6 @@ namespace System.Management.Automation.Runspaces
|
|||
}
|
||||
}
|
||||
|
||||
#if !CORECLR // Workflow Not Supported On CSS
|
||||
private static List<string> allowedAliases = new List<string>
|
||||
{
|
||||
"compare",
|
||||
"diff",
|
||||
"%",
|
||||
"foreach",
|
||||
"exsn",
|
||||
"fc",
|
||||
"fl",
|
||||
"ft",
|
||||
"fw",
|
||||
"gcm",
|
||||
"gjb",
|
||||
"gmo",
|
||||
"gv",
|
||||
"group",
|
||||
"ipmo",
|
||||
"measure",
|
||||
"rv",
|
||||
"rcjb",
|
||||
"rjb",
|
||||
"rmo",
|
||||
"rujb",
|
||||
"select",
|
||||
"set",
|
||||
"sv",
|
||||
"sort",
|
||||
"spjb",
|
||||
"sujb",
|
||||
"wjb",
|
||||
"?",
|
||||
"where"
|
||||
};
|
||||
|
||||
private static InitialSessionState CreateRestrictedForWorkflowServer()
|
||||
{
|
||||
InitialSessionState iss = CreateDefault();
|
||||
iss.LanguageMode = PSLanguageMode.NoLanguage;
|
||||
iss.ThrowOnRunspaceOpenError = true;
|
||||
iss.UseFullLanguageModeInDebugger = false;
|
||||
|
||||
// WIN8:551312 M3P endpoint should have NO application exposed
|
||||
//
|
||||
foreach (SessionStateCommandEntry entry in iss.Commands)
|
||||
{
|
||||
if (entry is SessionStateApplicationEntry)
|
||||
{
|
||||
iss.Commands.Remove(entry.Name, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// restrict what gets exposed
|
||||
//
|
||||
|
||||
List<string> allowedCommands = new List<string>();
|
||||
allowedCommands.AddRange(JobCmdlets);
|
||||
allowedCommands.AddRange(ImplicitRemotingCmdlets);
|
||||
allowedCommands.AddRange(MiscCmdlets);
|
||||
allowedCommands.AddRange(AutoDiscoveryCmdlets);
|
||||
|
||||
// make all other commands private
|
||||
MakeDisallowedEntriesPrivate(
|
||||
iss.Commands,
|
||||
allowedCommands,
|
||||
commandEntry => commandEntry.Name);
|
||||
|
||||
foreach (SessionStateCommandEntry entry in iss.Commands)
|
||||
{
|
||||
if (entry is SessionStateAliasEntry)
|
||||
{
|
||||
if (allowedAliases.Contains(entry.Name, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
entry.Visibility = SessionStateEntryVisibility.Public;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.Visibility = SessionStateEntryVisibility.Private;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Porting note: copy so it can be modified
|
||||
List<string> allowedFormats = new List<string>(Platform.FormatFileNames);
|
||||
RemoveDisallowedEntries(
|
||||
iss.Formats,
|
||||
allowedFormats,
|
||||
formatEntry => IO.Path.GetFileName(formatEntry.FileName));
|
||||
|
||||
// Porting note: type files were deprecated
|
||||
List<string> allowedTypes = new List<string>();
|
||||
allowedTypes.AddRange(DefaultTypeFiles);
|
||||
RemoveDisallowedEntries(
|
||||
iss.Types,
|
||||
allowedTypes,
|
||||
typeEntry => IO.Path.GetFileName(typeEntry.FileName));
|
||||
|
||||
iss.Variables.Clear(); // no variables are needed for workflow server - remove all of them
|
||||
|
||||
return iss;
|
||||
}
|
||||
|
||||
private static InitialSessionState CreateRestrictedForWorkflowServerWithFullLanguage()
|
||||
{
|
||||
InitialSessionState iss = CreateDefault();
|
||||
|
||||
iss.LanguageMode = PSLanguageMode.FullLanguage;
|
||||
iss.ThrowOnRunspaceOpenError = true;
|
||||
iss.UseFullLanguageModeInDebugger = false;
|
||||
|
||||
// WIN8:551312 M3P endpoint should have NO application exposed
|
||||
//
|
||||
foreach (SessionStateCommandEntry entry in iss.Commands)
|
||||
{
|
||||
if (entry is SessionStateApplicationEntry)
|
||||
{
|
||||
iss.Commands.Remove(entry.Name, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// restrict what gets exposed
|
||||
//
|
||||
|
||||
List<string> allowedCommands = new List<string>();
|
||||
allowedCommands.AddRange(JobCmdlets);
|
||||
allowedCommands.AddRange(ImplicitRemotingCmdlets);
|
||||
allowedCommands.AddRange(MiscCmdlets);
|
||||
allowedCommands.AddRange(MiscCommands);
|
||||
allowedCommands.AddRange(AutoDiscoveryCmdlets);
|
||||
allowedCommands.AddRange(LanguageHelperCmdlets);
|
||||
// Exposing Debug cmdlets in only Full language WF server
|
||||
// because for debugging one needs full language capabilities
|
||||
allowedCommands.AddRange(DebugCmdlets);
|
||||
|
||||
// make all other commands private
|
||||
MakeDisallowedEntriesPrivate(
|
||||
iss.Commands,
|
||||
allowedCommands,
|
||||
commandEntry => commandEntry.Name);
|
||||
|
||||
foreach (SessionStateCommandEntry entry in iss.Commands)
|
||||
{
|
||||
if (entry is SessionStateAliasEntry)
|
||||
{
|
||||
if (allowedAliases.Contains(entry.Name, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
entry.Visibility = SessionStateEntryVisibility.Public;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.Visibility = SessionStateEntryVisibility.Private;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Porting note: copy so it can be modified
|
||||
List<string> allowedFormats = new List<string>(Platform.FormatFileNames);
|
||||
RemoveDisallowedEntries(
|
||||
iss.Formats,
|
||||
allowedFormats,
|
||||
formatEntry => IO.Path.GetFileName(formatEntry.FileName));
|
||||
|
||||
// Porting note: type files were deprecated
|
||||
List<string> allowedTypes = new List<string>();
|
||||
allowedTypes.AddRange(DefaultTypeFiles);
|
||||
RemoveDisallowedEntries(
|
||||
iss.Types,
|
||||
allowedTypes,
|
||||
typeEntry => IO.Path.GetFileName(typeEntry.FileName));
|
||||
|
||||
iss.Variables.Clear(); // no variables are needed for workflow server - remove all of them
|
||||
// set a preference variable to indicate Get-Command should show
|
||||
// return only loaded public commands
|
||||
Hashtable parameters = new Hashtable { { "Get-Command:ListImported", true } };
|
||||
iss.Variables.Add(new SessionStateVariableEntry("PSDefaultParameterValues", parameters, "Default Get-Command Action"));
|
||||
return iss;
|
||||
}
|
||||
|
||||
private static InitialSessionState CreateRestrictedForWorkflowServerMinimum()
|
||||
{
|
||||
InitialSessionState iss = CreateDefault();
|
||||
iss.LanguageMode = PSLanguageMode.NoLanguage;
|
||||
iss.ThrowOnRunspaceOpenError = true;
|
||||
iss.UseFullLanguageModeInDebugger = false;
|
||||
|
||||
// WIN8:551312 M3P endpoint should have NO application exposed
|
||||
//
|
||||
foreach (SessionStateCommandEntry entry in iss.Commands)
|
||||
{
|
||||
if (entry.GetType() == typeof(SessionStateApplicationEntry))
|
||||
{
|
||||
iss.Commands.Remove(entry.Name, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// restrict what gets exposed
|
||||
//
|
||||
|
||||
// required by implicit remoting and interactive remoting
|
||||
List<string> allowedCommands = new List<string>
|
||||
{
|
||||
"Get-Command"
|
||||
};
|
||||
allowedCommands.AddRange(JobCmdlets);
|
||||
allowedCommands.AddRange(MiscCmdlets);
|
||||
|
||||
// make all other commands private
|
||||
MakeDisallowedEntriesPrivate(
|
||||
iss.Commands,
|
||||
allowedCommands,
|
||||
commandEntry => commandEntry.Name);
|
||||
|
||||
iss.Formats.Clear();
|
||||
List<string> allowedTypes = new List<string>();
|
||||
allowedTypes.AddRange(DefaultTypeFiles);
|
||||
RemoveDisallowedEntries(
|
||||
iss.Types,
|
||||
allowedTypes,
|
||||
typeEntry => IO.Path.GetFileName(typeEntry.FileName));
|
||||
|
||||
iss.Variables.Clear(); // no variables are needed for workflow server - remove all of them
|
||||
|
||||
// Disable module autodiscovery
|
||||
SessionStateVariableEntry ssve = new SessionStateVariableEntry("PSDisableModuleAutoDiscovery",
|
||||
true, "True if we disable module autodiscovery", ScopedItemOptions.Constant);
|
||||
iss.Variables.Add(ssve);
|
||||
|
||||
return iss;
|
||||
}
|
||||
|
||||
private static readonly string[] JobCmdlets = {
|
||||
"Get-Job", "Stop-Job", "Wait-Job", "Suspend-Job", "Resume-Job",
|
||||
"Remove-Job", "Receive-Job"
|
||||
};
|
||||
|
||||
private static readonly string[] ImplicitRemotingCmdlets = {
|
||||
"Get-Command", "Select-Object", "Measure-Object",
|
||||
"Get-Help", "Get-FormatData", "Exit-PSSession",
|
||||
"Out-Default"
|
||||
};
|
||||
|
||||
private static readonly string[] AutoDiscoveryCmdlets = { "Get-Module" };
|
||||
|
||||
private static readonly string[] LanguageHelperCmdlets = {
|
||||
"Compare-Object",
|
||||
"ForEach-Object",
|
||||
"Group-Object",
|
||||
"Sort-Object",
|
||||
"Where-Object",
|
||||
"Out-File",
|
||||
"Out-Null",
|
||||
"Out-String",
|
||||
"Format-Custom",
|
||||
"Format-List",
|
||||
"Format-Table",
|
||||
"Format-Wide",
|
||||
"Remove-Module",
|
||||
"Get-Variable",
|
||||
"Set-Variable",
|
||||
"Remove-Variable",
|
||||
"Get-Credential",
|
||||
"Set-StrictMode"
|
||||
};
|
||||
/// <summary>
|
||||
/// Following cmdlets are needed for debugging support starting WinBlue
|
||||
/// </summary>
|
||||
private static readonly string[] DebugCmdlets = {
|
||||
"Disable-PSBreakpoint",
|
||||
"Enable-PSBreakpoint",
|
||||
"Get-PSBreakpoint",
|
||||
"Remove-PSBreakpoint",
|
||||
"Set-PSBreakpoint"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// this cmdlets are exposed due to some bugs. Need to figure out if
|
||||
/// they are still required
|
||||
/// </summary>
|
||||
private static readonly string[] MiscCmdlets = { "Join-Path", "Import-Module" };
|
||||
private static readonly string[] MiscCommands = { "TabExpansion2" };
|
||||
|
||||
private static readonly string[] DefaultTypeFiles = { "types.ps1xml", "typesv3.ps1xml" };
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
@ -2705,10 +2296,6 @@ namespace System.Management.Automation.Runspaces
|
|||
bool etwEnabled = RunspaceEventSource.Log.IsEnabled();
|
||||
if (etwEnabled) RunspaceEventSource.Log.LoadCommandsStart();
|
||||
|
||||
#if !CORECLR // Workflow Not Supported On CSS
|
||||
InitialSessionState cloneForWorkflowDefinitions = null;
|
||||
#endif
|
||||
|
||||
foreach (SessionStateCommandEntry cmd in Commands)
|
||||
{
|
||||
if (etwEnabled) RunspaceEventSource.Log.LoadCommandStart(cmd.Name);
|
||||
|
@ -2760,25 +2347,7 @@ namespace System.Management.Automation.Runspaces
|
|||
}
|
||||
continue;
|
||||
}
|
||||
#if !CORECLR // Workflow Not Supported On CSS
|
||||
SessionStateWorkflowEntry sswe = cmd as SessionStateWorkflowEntry;
|
||||
if (sswe != null)
|
||||
{
|
||||
if (cloneForWorkflowDefinitions == null)
|
||||
{
|
||||
cloneForWorkflowDefinitions = this.Clone();
|
||||
var commandsCopy =
|
||||
cloneForWorkflowDefinitions.Commands.Where(e => !(e is SessionStateWorkflowEntry))
|
||||
.ToList();
|
||||
cloneForWorkflowDefinitions.Commands.Clear();
|
||||
foreach (var c in commandsCopy)
|
||||
{
|
||||
cloneForWorkflowDefinitions.Commands.Add(c);
|
||||
}
|
||||
}
|
||||
ss.AddSessionStateEntry(cloneForWorkflowDefinitions, sswe);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (etwEnabled) RunspaceEventSource.Log.LoadCommandStop(cmd.Name);
|
||||
}
|
||||
|
||||
|
|
|
@ -1228,7 +1228,7 @@ namespace Microsoft.PowerShell.Commands
|
|||
{
|
||||
if (moduleInfo.RootModuleForManifest != null)
|
||||
{
|
||||
if (moduleInfo.RootModuleForManifest.EndsWith(StringLiterals.DependentWorkflowAssemblyExtension, StringComparison.OrdinalIgnoreCase))
|
||||
if (moduleInfo.RootModuleForManifest.EndsWith(StringLiterals.PowerShellILAssemblyExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
moduleInfo.SetModuleType(ModuleType.Binary);
|
||||
}
|
||||
|
@ -1256,7 +1256,7 @@ namespace Microsoft.PowerShell.Commands
|
|||
moduleInfo.RootModule = moduleInfo.Path;
|
||||
}
|
||||
}
|
||||
else if (extension.Equals(StringLiterals.DependentWorkflowAssemblyExtension, StringComparison.OrdinalIgnoreCase) || extension.Equals(StringLiterals.PowerShellNgenAssemblyExtension, StringComparison.OrdinalIgnoreCase))
|
||||
else if (extension.Equals(StringLiterals.PowerShellILAssemblyExtension, StringComparison.OrdinalIgnoreCase) || extension.Equals(StringLiterals.PowerShellNgenAssemblyExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
moduleInfo.SetModuleType(ModuleType.Binary);
|
||||
moduleInfo.RootModule = moduleInfo.Path;
|
||||
|
@ -2203,7 +2203,7 @@ namespace Microsoft.PowerShell.Commands
|
|||
iss.Assemblies.Add(new SessionStateAssemblyEntry(assembly, fileName));
|
||||
fixedUpAssemblyPathList.Add(fileName);
|
||||
|
||||
fileName = FixupFileName(moduleBase, assembly, StringLiterals.DependentWorkflowAssemblyExtension);
|
||||
fileName = FixupFileName(moduleBase, assembly, StringLiterals.PowerShellILAssemblyExtension);
|
||||
|
||||
loadMessage = StringUtil.Format(Modules.LoadingFile, "Assembly", fileName);
|
||||
WriteVerbose(loadMessage);
|
||||
|
|
|
@ -480,7 +480,7 @@ namespace System.Management.Automation
|
|||
StringLiterals.PowerShellCmdletizationFileExtension,
|
||||
StringLiterals.WorkflowFileExtension,
|
||||
StringLiterals.PowerShellNgenAssemblyExtension,
|
||||
StringLiterals.DependentWorkflowAssemblyExtension};
|
||||
StringLiterals.PowerShellILAssemblyExtension};
|
||||
|
||||
// A list of the extensions to check for implicit module loading and discovery, put the ni.dll in front of .dll to have higher priority to be loaded.
|
||||
internal static string[] PSModuleExtensions = new string[] {
|
||||
|
@ -489,7 +489,7 @@ namespace System.Management.Automation
|
|||
StringLiterals.PowerShellCmdletizationFileExtension,
|
||||
StringLiterals.WorkflowFileExtension,
|
||||
StringLiterals.PowerShellNgenAssemblyExtension,
|
||||
StringLiterals.DependentWorkflowAssemblyExtension};
|
||||
StringLiterals.PowerShellILAssemblyExtension};
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the extension is one of the module extensions...
|
||||
|
|
|
@ -160,7 +160,7 @@ namespace Microsoft.PowerShell.Commands
|
|||
foreach (ModuleSpecification nestedModule in nestedModules)
|
||||
{
|
||||
if (!IsValidFilePath(nestedModule.Name, module, true)
|
||||
&& !IsValidFilePath(nestedModule.Name + StringLiterals.DependentWorkflowAssemblyExtension, module, true)
|
||||
&& !IsValidFilePath(nestedModule.Name + StringLiterals.PowerShellILAssemblyExtension, module, true)
|
||||
&& !IsValidFilePath(nestedModule.Name + StringLiterals.PowerShellNgenAssemblyExtension, module, true)
|
||||
&& !IsValidFilePath(nestedModule.Name + StringLiterals.PowerShellModuleFileExtension, module, true)
|
||||
&& !IsValidGacAssembly(nestedModule.Name))
|
||||
|
@ -350,9 +350,9 @@ namespace Microsoft.PowerShell.Commands
|
|||
string gacPath = System.Environment.GetEnvironmentVariable("windir") + "\\Microsoft.NET\\assembly";
|
||||
string assemblyFile = assemblyName;
|
||||
string ngenAssemblyFile = assemblyName;
|
||||
if (!assemblyName.EndsWith(StringLiterals.DependentWorkflowAssemblyExtension, StringComparison.OrdinalIgnoreCase))
|
||||
if (!assemblyName.EndsWith(StringLiterals.PowerShellILAssemblyExtension, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
assemblyFile = assemblyName + StringLiterals.DependentWorkflowAssemblyExtension;
|
||||
assemblyFile = assemblyName + StringLiterals.PowerShellILAssemblyExtension;
|
||||
ngenAssemblyFile = assemblyName + StringLiterals.PowerShellNgenAssemblyExtension;
|
||||
}
|
||||
try
|
||||
|
|
|
@ -32,22 +32,6 @@ namespace System.Management.Automation
|
|||
fn.ScriptBlock.LanguageMode = PSLanguageMode.FullLanguage;
|
||||
}
|
||||
|
||||
#if !CORECLR // Workflow Not Supported On CSS
|
||||
internal void AddSessionStateEntry(InitialSessionState initialSessionState, SessionStateWorkflowEntry entry)
|
||||
{
|
||||
var converterInstance = Utils.GetAstToWorkflowConverterAndEnsureWorkflowModuleLoaded(null);
|
||||
|
||||
var workflowInfo = entry.WorkflowInfo ??
|
||||
converterInstance.CompileWorkflow(entry.Name, entry.Definition, initialSessionState);
|
||||
|
||||
WorkflowInfo wf = new WorkflowInfo(workflowInfo);
|
||||
|
||||
wf = this.SetWorkflowRaw(wf, CommandOrigin.Internal);
|
||||
wf.Visibility = entry.Visibility;
|
||||
wf.Module = entry.Module;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flattened view of the functions that are visible using
|
||||
/// the current scope as a reference and filtering the functions in
|
||||
|
@ -300,60 +284,6 @@ namespace System.Management.Automation
|
|||
return functionInfo;
|
||||
} // SetFunctionRaw
|
||||
|
||||
internal WorkflowInfo SetWorkflowRaw(
|
||||
WorkflowInfo workflowInfo,
|
||||
CommandOrigin origin)
|
||||
{
|
||||
string originalName = workflowInfo.Name;
|
||||
string name = originalName;
|
||||
|
||||
FunctionLookupPath path = new FunctionLookupPath(name);
|
||||
name = path.UnqualifiedPath;
|
||||
|
||||
if (String.IsNullOrEmpty(name))
|
||||
{
|
||||
SessionStateException exception =
|
||||
new SessionStateException(
|
||||
originalName,
|
||||
SessionStateCategory.Function,
|
||||
"ScopedFunctionMustHaveName",
|
||||
SessionStateStrings.ScopedFunctionMustHaveName,
|
||||
ErrorCategory.InvalidArgument);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
|
||||
ScopedItemOptions options = ScopedItemOptions.None;
|
||||
if (path.IsPrivate)
|
||||
{
|
||||
options |= ScopedItemOptions.Private;
|
||||
}
|
||||
|
||||
FunctionScopeItemSearcher searcher =
|
||||
new FunctionScopeItemSearcher(
|
||||
this,
|
||||
path,
|
||||
origin);
|
||||
|
||||
// The script that defines a workflowInfo wrapper is fully trusted
|
||||
workflowInfo.ScriptBlock.LanguageMode = PSLanguageMode.FullLanguage;
|
||||
|
||||
if (workflowInfo.Module == null && this.Module != null)
|
||||
{
|
||||
workflowInfo.Module = this.Module;
|
||||
}
|
||||
|
||||
var wfInfo = (WorkflowInfo)
|
||||
searcher.InitialScope.SetFunction(name, workflowInfo.ScriptBlock, null, options, false, origin, ExecutionContext, null,
|
||||
(arg1, arg2, arg3, arg4, arg5, arg6) => workflowInfo);
|
||||
foreach (var aliasName in GetFunctionAliases(workflowInfo.ScriptBlock.Ast as IParameterMetadataProvider))
|
||||
{
|
||||
searcher.InitialScope.SetAliasValue(aliasName, name, ExecutionContext, false, origin);
|
||||
}
|
||||
|
||||
return wfInfo;
|
||||
} // SetWorkflowRaw
|
||||
|
||||
/// <summary>
|
||||
/// Set a function in the current scope of session state.
|
||||
/// </summary>
|
||||
|
@ -557,7 +487,7 @@ namespace System.Management.Automation
|
|||
/// </param>
|
||||
///
|
||||
/// <param name="isPreValidated">
|
||||
/// Set to true if it is a regular function (meaning, we do not need to check this is a workflow or if the script contains JobDefinition Attribute and then process it)
|
||||
/// Set to true if it is a regular function (meaning, we do not need to check if the script contains JobDefinition Attribute and then process it)
|
||||
/// </param>
|
||||
///
|
||||
/// <exception cref="ArgumentException">
|
||||
|
|
|
@ -138,7 +138,7 @@ namespace System.Management.Automation
|
|||
/// <summary>
|
||||
/// The file extension (including the dot) of an workflow dependent assembly
|
||||
/// </summary>
|
||||
internal const string DependentWorkflowAssemblyExtension = ".dll";
|
||||
internal const string PowerShellILAssemblyExtension = ".dll";
|
||||
|
||||
/// <summary>
|
||||
/// The file extension (including the dot) of an workflow dependent Ngen assembly
|
||||
|
|
|
@ -622,47 +622,6 @@ namespace System.Management.Automation
|
|||
/// </summary>
|
||||
internal const string ScheduledJobModuleName = "PSScheduledJob";
|
||||
|
||||
internal const string WorkflowType = "Microsoft.PowerShell.Workflow.AstToWorkflowConverter, Microsoft.PowerShell.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
|
||||
internal const string WorkflowModule = "PSWorkflow";
|
||||
|
||||
internal static IAstToWorkflowConverter GetAstToWorkflowConverterAndEnsureWorkflowModuleLoaded(ExecutionContext context)
|
||||
{
|
||||
IAstToWorkflowConverter converterInstance = null;
|
||||
Type converterType = null;
|
||||
|
||||
if (Utils.IsRunningFromSysWOW64())
|
||||
{
|
||||
throw new NotSupportedException(AutomationExceptions.WorkflowDoesNotSupportWOW64);
|
||||
}
|
||||
|
||||
// If the current language mode is ConstrainedLanguage but the system lockdown mode is not,
|
||||
// then also block the conversion - since we can't validate the InlineScript, PowerShellValue,
|
||||
// etc.
|
||||
if ((context != null) &&
|
||||
(context.LanguageMode == PSLanguageMode.ConstrainedLanguage) &&
|
||||
(SystemPolicy.GetSystemLockdownPolicy() != SystemEnforcementMode.Enforce))
|
||||
{
|
||||
throw new NotSupportedException(Modules.CannotDefineWorkflowInconsistentLanguageMode);
|
||||
}
|
||||
|
||||
EnsureModuleLoaded(WorkflowModule, context);
|
||||
|
||||
converterType = Type.GetType(WorkflowType);
|
||||
|
||||
if (converterType != null)
|
||||
{
|
||||
converterInstance = (IAstToWorkflowConverter)converterType.GetConstructor(PSTypeExtensions.EmptyTypes).Invoke(EmptyArray<object>());
|
||||
}
|
||||
|
||||
if (converterInstance == null)
|
||||
{
|
||||
string error = StringUtil.Format(AutomationExceptions.CantLoadWorkflowType, Utils.WorkflowType, Utils.WorkflowModule);
|
||||
throw new NotSupportedException(error);
|
||||
}
|
||||
|
||||
return converterInstance;
|
||||
}
|
||||
|
||||
internal static void EnsureModuleLoaded(string module, ExecutionContext context)
|
||||
{
|
||||
if (context != null && !context.AutoLoadingModuleInProgress.Contains(module))
|
||||
|
@ -1107,24 +1066,12 @@ namespace System.Management.Automation
|
|||
internal static readonly HashSet<string> PowerShellAssemblies =
|
||||
new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
"microsoft.powershell.activities",
|
||||
"microsoft.powershell.commands.diagnostics",
|
||||
"microsoft.powershell.commands.management",
|
||||
"microsoft.powershell.commands.utility",
|
||||
"microsoft.powershell.consolehost",
|
||||
"microsoft.powershell.core.activities",
|
||||
"microsoft.powershell.diagnostics.activities",
|
||||
"microsoft.powershell.editor",
|
||||
"microsoft.powershell.gpowershell",
|
||||
"microsoft.powershell.graphicalhost",
|
||||
"microsoft.powershell.isecommon",
|
||||
"microsoft.powershell.management.activities",
|
||||
"microsoft.powershell.scheduledjob",
|
||||
"microsoft.powershell.security.activities",
|
||||
"microsoft.powershell.security",
|
||||
"microsoft.powershell.utility.activities",
|
||||
"microsoft.powershell.workflow.servicecore",
|
||||
"microsoft.wsman.management.activities",
|
||||
"microsoft.wsman.management",
|
||||
"microsoft.wsman.runtime",
|
||||
"system.management.automation"
|
||||
|
|
|
@ -206,8 +206,6 @@ namespace System.Management.Automation.Language
|
|||
|
||||
internal static readonly MethodInfo FunctionOps_DefineFunction =
|
||||
typeof(FunctionOps).GetMethod(nameof(FunctionOps.DefineFunction), staticFlags);
|
||||
internal static readonly MethodInfo FunctionOps_DefineWorkflows =
|
||||
typeof(FunctionOps).GetMethod(nameof(FunctionOps.DefineWorkflows), staticFlags);
|
||||
|
||||
internal static readonly ConstructorInfo Hashtable_ctor =
|
||||
typeof(Hashtable).GetConstructor(BindingFlags.Instance | BindingFlags.Public, null,
|
||||
|
@ -2893,26 +2891,8 @@ namespace System.Management.Automation.Language
|
|||
return this.VisitPipeline(dynamicKeywordAst.GenerateCommandCallPipelineAst());
|
||||
}
|
||||
|
||||
private bool _generatedCallToDefineWorkflows;
|
||||
public object VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst)
|
||||
{
|
||||
if (functionDefinitionAst.IsWorkflow)
|
||||
{
|
||||
if (_generatedCallToDefineWorkflows)
|
||||
return ExpressionCache.Empty;
|
||||
|
||||
var topAst = functionDefinitionAst.Parent;
|
||||
while (!(topAst is ScriptBlockAst))
|
||||
{
|
||||
topAst = topAst.Parent;
|
||||
}
|
||||
|
||||
_generatedCallToDefineWorkflows = true;
|
||||
return Expression.Call(CachedReflectionInfo.FunctionOps_DefineWorkflows,
|
||||
_executionContextParameter,
|
||||
Expression.Constant(topAst, typeof(ScriptBlockAst)));
|
||||
}
|
||||
|
||||
return Expression.Call(CachedReflectionInfo.FunctionOps_DefineFunction,
|
||||
_executionContextParameter,
|
||||
Expression.Constant(functionDefinitionAst),
|
||||
|
|
|
@ -400,20 +400,7 @@ namespace System.Management.Automation.Language
|
|||
|
||||
if (functionDefinitionAst.IsWorkflow)
|
||||
{
|
||||
#if !CORECLR // Workflow Not Supported On CSS
|
||||
try
|
||||
{
|
||||
var converterInstance = Utils.GetAstToWorkflowConverterAndEnsureWorkflowModuleLoaded(null);
|
||||
List<ParseError> parseErrors = converterInstance.ValidateAst(functionDefinitionAst);
|
||||
foreach (ParseError error in parseErrors)
|
||||
{
|
||||
_parser.ReportError(error);
|
||||
}
|
||||
}
|
||||
catch (NotSupportedException) { }
|
||||
#else
|
||||
_parser.ReportError(functionDefinitionAst.Extent, () => ParserStrings.WorkflowNotSupportedInPowerShellCore);
|
||||
#endif
|
||||
}
|
||||
|
||||
return AstVisitAction.Continue;
|
||||
|
|
|
@ -10057,35 +10057,3 @@ namespace System.Management.Automation.Language
|
|||
|
||||
#endregion Help
|
||||
}
|
||||
|
||||
namespace System.Management.Automation.Internal
|
||||
{
|
||||
using Runspaces;
|
||||
using Language;
|
||||
|
||||
/// <summary>Internal interface used for workflow compilation.</summary>
|
||||
[SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")]
|
||||
public interface IAstToWorkflowConverter
|
||||
{
|
||||
/// <summary/>
|
||||
List<ParseError> ValidateAst(FunctionDefinitionAst ast);
|
||||
|
||||
/// <summary/>
|
||||
List<WorkflowInfo> CompileWorkflows(ScriptBlockAst ast, PSModuleInfo definingModule);
|
||||
|
||||
/// <summary/>
|
||||
List<WorkflowInfo> CompileWorkflows(ScriptBlockAst ast, PSModuleInfo definingModule, InitialSessionState initialSessionState, out ParseException parsingErrors);
|
||||
|
||||
/// <summary/>
|
||||
List<WorkflowInfo> CompileWorkflows(ScriptBlockAst ast, PSModuleInfo definingModule, InitialSessionState initialSessionState, PSLanguageMode? languageMode, out ParseException parsingErrors);
|
||||
|
||||
/// <summary/>
|
||||
List<WorkflowInfo> CompileWorkflows(ScriptBlockAst ast, PSModuleInfo definingModule, string rootWorkflowName);
|
||||
|
||||
/// <summary/>
|
||||
List<WorkflowInfo> CompileWorkflows(ScriptBlockAst ast, PSModuleInfo definingModule, InitialSessionState initialSessionState, out ParseException parsingErrors, string rootWorkflowName);
|
||||
|
||||
/// <summary/>
|
||||
WorkflowInfo CompileWorkflow(string name, string definition, InitialSessionState initialSessionState);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1211,40 +1211,6 @@ namespace System.Management.Automation
|
|||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DefineWorkflows(ExecutionContext context, ScriptBlockAst scriptBlockAst)
|
||||
{
|
||||
ParseException parseErrors = null;
|
||||
|
||||
try
|
||||
{
|
||||
var converterInstance = Utils.GetAstToWorkflowConverterAndEnsureWorkflowModuleLoaded(context);
|
||||
PSLanguageMode? languageMode = (context != null) ? context.LanguageMode : (PSLanguageMode?) null;
|
||||
var workflows = converterInstance.CompileWorkflows(scriptBlockAst, context.EngineSessionState.Module, null, languageMode, out parseErrors);
|
||||
foreach (var workflow in workflows)
|
||||
{
|
||||
context.EngineSessionState.SetWorkflowRaw(workflow,
|
||||
context.EngineSessionState.CurrentScope.ScopeOrigin);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var rte = exception as RuntimeException;
|
||||
if (rte == null)
|
||||
{
|
||||
throw ExceptionHandlingOps.ConvertToRuntimeException(exception, scriptBlockAst.Extent);
|
||||
}
|
||||
|
||||
InterpreterError.UpdateExceptionErrorRecordPosition(rte, scriptBlockAst.Extent);
|
||||
throw;
|
||||
}
|
||||
|
||||
if (parseErrors != null && parseErrors.Errors != null)
|
||||
{
|
||||
InterpreterError.UpdateExceptionErrorRecordPosition(parseErrors, scriptBlockAst.Extent);
|
||||
throw parseErrors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ScriptBlockExpressionWrapper
|
||||
|
|
|
@ -195,9 +195,6 @@
|
|||
<data name="CantConvertPipelineStartsWithExpression" xml:space="preserve">
|
||||
<value>Cannot generate a PowerShell object for a ScriptBlock that starts a pipeline with an expression.</value>
|
||||
</data>
|
||||
<data name="CantLoadWorkflowType" xml:space="preserve">
|
||||
<value>Cannot create workflow. The type '{0}' from the '{1}' module could not be loaded.</value>
|
||||
</data>
|
||||
<data name="WorkflowDoesNotSupportWOW64" xml:space="preserve">
|
||||
<value>Windows PowerShell Workflow is not supported in a Windows PowerShell x86-based console. Open a Windows PowerShell x64-based console, and then try again.</value>
|
||||
</data>
|
||||
|
|
|
@ -592,9 +592,6 @@
|
|||
<value>A CIM provider for module discovery was not found on the CIM server. {0}</value>
|
||||
<comment>{0} is a placeholder for a more detailed error message</comment>
|
||||
</data>
|
||||
<data name="CannotDefineWorkflowInconsistentLanguageMode" xml:space="preserve">
|
||||
<value>Cannot define the workflow. The language mode for this session is incompatible with the system-wide language mode.</value>
|
||||
</data>
|
||||
<data name="XamlWorkflowsNotSupported" xml:space="preserve">
|
||||
<value>Cannot load the workflow. Only signed in-box XAML-based workflows or script-based workflows are supported in the current language mode.</value>
|
||||
</data>
|
||||
|
|
Loading…
Reference in a new issue