diff --git a/src/System.Management.Automation/engine/ExecutionContext.cs b/src/System.Management.Automation/engine/ExecutionContext.cs index 889044b9b4f..0c5d27cc02b 100644 --- a/src/System.Management.Automation/engine/ExecutionContext.cs +++ b/src/System.Management.Automation/engine/ExecutionContext.cs @@ -366,7 +366,7 @@ internal bool UseFullLanguageModeInDebugger }; /// - /// Is true the PSScheduledJob and PSWorkflow modules are loaded for this runspace + /// Is true if the PSScheduledJob module is loaded for this runspace /// internal bool IsModuleWithJobSourceAdapterLoaded { diff --git a/src/System.Management.Automation/engine/GetCommandCommand.cs b/src/System.Management.Automation/engine/GetCommandCommand.cs index 34a065c2ff0..a05047c9138 100644 --- a/src/System.Management.Automation/engine/GetCommandCommand.cs +++ b/src/System.Management.Automation/engine/GetCommandCommand.cs @@ -26,7 +26,7 @@ namespace Microsoft.PowerShell.Commands [Cmdlet(VerbsCommon.Get, "Command", DefaultParameterSetName = "CmdletSet", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113309")] [OutputType(typeof(AliasInfo), typeof(ApplicationInfo), typeof(FunctionInfo), typeof(CmdletInfo), typeof(ExternalScriptInfo), typeof(FilterInfo), - typeof(WorkflowInfo), typeof(string), typeof(PSObject))] + typeof(string), typeof(PSObject))] public sealed class GetCommandCommand : PSCmdlet { #region Definitions of cmdlet parameters diff --git a/src/System.Management.Automation/engine/Modules/AnalysisCache.cs b/src/System.Management.Automation/engine/Modules/AnalysisCache.cs index 9dda14d5f4c..f2f82586fef 100644 --- a/src/System.Management.Automation/engine/Modules/AnalysisCache.cs +++ b/src/System.Management.Automation/engine/Modules/AnalysisCache.cs @@ -72,10 +72,6 @@ internal static ConcurrentDictionary GetExportedCommands(s { result = AnalyzeCdxmlModule(modulePath, context, lastWriteTime); } - else if (extension.Equals(StringLiterals.WorkflowFileExtension, StringComparison.OrdinalIgnoreCase)) - { - result = AnalyzeXamlModule(modulePath, context, lastWriteTime); - } else if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase)) { result = AnalyzeDllModule(modulePath, context, lastWriteTime); @@ -366,11 +362,6 @@ private static ConcurrentDictionary AnalyzeScriptModule(st return result; } - private static ConcurrentDictionary AnalyzeXamlModule(string modulePath, ExecutionContext context, DateTime lastWriteTime) - { - return AnalyzeTheOldWay(modulePath, context, lastWriteTime); - } - private static ConcurrentDictionary AnalyzeCdxmlModule(string modulePath, ExecutionContext context, DateTime lastWriteTime) { return AnalyzeTheOldWay(modulePath, context, lastWriteTime); diff --git a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs index d9a418314bc..9917f8c35d0 100644 --- a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs +++ b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs @@ -531,11 +531,6 @@ private PSModuleInfo ImportModule_LocallyViaName(ImportModuleOptions importModul { try { - if (name.Equals("PSWorkflow", StringComparison.OrdinalIgnoreCase) && Utils.IsRunningFromSysWOW64()) - { - throw new NotSupportedException(AutomationExceptions.WorkflowDoesNotSupportWOW64); - } - bool found = false; PSModuleInfo foundModule = null; diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index db474b4e1a0..037b9651bbe 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -88,13 +88,6 @@ protected internal struct ImportModuleOptions /// If Scope parameter is Local, this is true. /// internal bool Local; - - /// - /// Win8:90779 - /// ServiceCore assembly is automatically imported as a nested module to process the NestedModules/RootModules/RequiredAssemblies fields in module manifests. - /// This property is set to ensure that Import-Module of a manifest module does not expose "Import-psworkflow" cmdlet. - /// - internal bool ServiceCoreAutoAdded; } /// @@ -263,11 +256,6 @@ internal List MatchAll "ModuleVersion" }; - private static List s_serviceCoreAssemblyCmdlets = new List(new string[] { - "Microsoft.PowerShell.Workflow.ServiceCore\\Import-PSWorkflow", - "Microsoft.PowerShell.Workflow.ServiceCore\\New-PSWorkflowExecutionOption", - }); - private Dictionary _currentlyProcessingModules = new Dictionary(); internal bool LoadUsingModulePath(bool found, IEnumerable modulePath, string name, SessionState ss, @@ -333,15 +321,9 @@ internal bool LoadUsingModulePath(PSModuleInfo parentModule, bool found, IEnumer if (found) { - // Cache the module's exported commands after importing it, or if the -Refresh flag is used on - // "Get-Module -List" + // Cache the module's exported commands after importing it, or if the -Refresh flag is used on "Get-Module -List" if ((module != null) && !module.HadErrorsLoading) { - if (module.ExportedWorkflows != null && module.ExportedWorkflows.Count > 0 && Utils.IsRunningFromSysWOW64()) - { - throw new NotSupportedException(AutomationExceptions.WorkflowDoesNotSupportWOW64); - } - AnalysisCache.CacheModuleExports(module, Context); } } @@ -1242,10 +1224,6 @@ private PSModuleInfo CreateModuleInfoForGetModule(string file, bool refresh) { moduleInfo.SetModuleType(ModuleType.Script); } - else if (moduleInfo.RootModuleForManifest.EndsWith(StringLiterals.WorkflowFileExtension, StringComparison.OrdinalIgnoreCase)) - { - moduleInfo.SetModuleType(ModuleType.Workflow); - } else if (moduleInfo.RootModuleForManifest.EndsWith(StringLiterals.PowerShellCmdletizationFileExtension, StringComparison.OrdinalIgnoreCase)) { moduleInfo.SetModuleType(ModuleType.Cim); @@ -1267,11 +1245,6 @@ private PSModuleInfo CreateModuleInfoForGetModule(string file, bool refresh) moduleInfo.SetModuleType(ModuleType.Binary); moduleInfo.RootModule = moduleInfo.Path; } - else if (extension.Equals(StringLiterals.WorkflowFileExtension, StringComparison.OrdinalIgnoreCase)) - { - moduleInfo.SetModuleType(ModuleType.Workflow); - moduleInfo.RootModule = moduleInfo.Path; - } else if (extension.Equals(StringLiterals.PowerShellCmdletizationFileExtension)) { moduleInfo.SetModuleType(ModuleType.Cim); @@ -1481,12 +1454,6 @@ internal PSModuleInfo LoadModuleManifest( // START: Check if the ModuleToProcess is already loaded..if it is, ignore the this load manifest // call and return - // Workflows specified in NestedModules from the manifest - List workflowsToProcess = new List(); - - // Workflows specified in RequiredAssemblies - List dependentWorkflows = new List(); - string moduleToProcess = null; if ( @@ -1547,9 +1514,8 @@ internal PSModuleInfo LoadModuleManifest( string actualRootModule = moduleToProcess ?? rootModule; - bool actualRootModuleIsXaml = false; - // For workflow modules, the actualRootModule is added to workflowsToProcess and is nulled out. - // We need to save this name so that we can assign this to the RootModule property of ModuleInfo + // If the root module is a workflow module, the 'actualRootModule' is nulled out. + // We need to save this name so that we can assign this to the RootModule property of ModuleInfo. string savedActualRootModule = actualRootModule; if (string.Equals(System.IO.Path.GetExtension(actualRootModule), @@ -1564,9 +1530,19 @@ internal PSModuleInfo LoadModuleManifest( throw invalidOperation; } - workflowsToProcess.Add(actualRootModule); + if (writingErrors) + { + message = StringUtil.Format(Modules.WorkflowModuleNotSupported, actualRootModule); + WriteError(new ErrorRecord( + new NotSupportedException(message), + "Modules_WorkflowModuleNotSupported", + ErrorCategory.InvalidOperation, null)); + } + + // Null out 'actualRootModule' so don't attempt to process the file like a non-workflow module later. actualRootModule = null; - actualRootModuleIsXaml = true; + containedErrors = true; + if (bailOnFirstError) { return null; } } // extract defaultCommandPrefix from the manifest @@ -2077,7 +2053,17 @@ internal PSModuleInfo LoadModuleManifest( if (string.Equals(System.IO.Path.GetExtension(s.Name), StringLiterals.WorkflowFileExtension, StringComparison.OrdinalIgnoreCase)) { - workflowsToProcess.Add(s.Name); + if (writingErrors) + { + message = StringUtil.Format(Modules.WorkflowModuleNotSupported, s.Name); + WriteError(new ErrorRecord( + new NotSupportedException(message), + "Modules_WorkflowModuleNotSupported", + ErrorCategory.InvalidOperation, null)); + } + + containedErrors = true; + if (bailOnFirstError) { return null; } } else { @@ -2174,15 +2160,7 @@ internal PSModuleInfo LoadModuleManifest( { foreach (string assembly in tmpAssemblyList) { - if (string.Equals(System.IO.Path.GetExtension(assembly), - StringLiterals.WorkflowFileExtension, StringComparison.OrdinalIgnoreCase)) - { - dependentWorkflows.Add(assembly); - } - else - { - assemblyList.Add(assembly); - } + assemblyList.Add(assembly); } } @@ -2845,31 +2823,7 @@ internal PSModuleInfo LoadModuleManifest( bool oldGLobal = this.BaseGlobal; this.BaseGlobal = false; - string shortModuleName = null; - if (nestedModuleSpecification.Name == _serviceCoreAssemblyFullName) - { - shortModuleName = _serviceCoreAssemblyShortName; - } - - PSModuleInfo nestedModule; - if ( - string.Equals(nestedModuleSpecification.Name, _serviceCoreAssemblyFullName, - StringComparison.OrdinalIgnoreCase) || - string.Equals(nestedModuleSpecification.Name, _serviceCoreAssemblyShortName, - StringComparison.OrdinalIgnoreCase)) - { - nestedModule = LoadServiceCoreModule( - manifestInfo, - moduleBase, - null, //SessionState - nestedModuleOptions, - manifestProcessingFlags, - false, // addToParentModuleIfFound - out found); - } - else - { - nestedModule = LoadModuleNamedInManifest( + PSModuleInfo nestedModule = LoadModuleNamedInManifest( manifestInfo, nestedModuleSpecification, // moduleName moduleBase, @@ -2882,8 +2836,7 @@ internal PSModuleInfo LoadModuleManifest( true, privateData, out found, - shortModuleName); - } + shortModuleName: null); this.BaseGlobal = oldGLobal; @@ -2894,27 +2847,20 @@ internal PSModuleInfo LoadModuleManifest( // exports if ((ss == null) && (nestedModule != null)) { - // If this was ServiceCore, don't process its exports - as these - // should not show up when a module defines WorkflowsToProcess - if ( - !String.Equals(nestedModule.Name, _serviceCoreAssemblyShortName, - StringComparison.OrdinalIgnoreCase)) + foreach (string detectedCmdlet in nestedModule.ExportedCmdlets.Keys) { - foreach (string detectedCmdlet in nestedModule.ExportedCmdlets.Keys) - { - manifestInfo.AddDetectedCmdletExport(detectedCmdlet); - } + manifestInfo.AddDetectedCmdletExport(detectedCmdlet); + } - foreach (var detectedFunction in nestedModule.ExportedFunctions.Keys) - { - manifestInfo.AddDetectedFunctionExport(detectedFunction); - } + foreach (var detectedFunction in nestedModule.ExportedFunctions.Keys) + { + manifestInfo.AddDetectedFunctionExport(detectedFunction); + } - foreach (string detectedAlias in nestedModule.ExportedAliases.Keys) - { - manifestInfo.AddDetectedAliasExport(detectedAlias, - nestedModule.ExportedAliases[detectedAlias].Definition); - } + foreach (string detectedAlias in nestedModule.ExportedAliases.Keys) + { + manifestInfo.AddDetectedAliasExport(detectedAlias, + nestedModule.ExportedAliases[detectedAlias].Definition); } } // If the NestedModules was a .ps1 script no module object would have been generated @@ -2937,74 +2883,6 @@ internal PSModuleInfo LoadModuleManifest( throw invalidOperation; } } - - if (actualRootModuleIsXaml) - { - manifestInfo.SetModuleType(ModuleType.Workflow); - } - - if (workflowsToProcess != null && workflowsToProcess.Count > 0) - { -#if CORECLR // Workflow Not Supported On CSS - PSNotSupportedException workflowModuleNotSupported = - PSTraceSource.NewNotSupportedException( - Modules.WorkflowModuleNotSupportedInPowerShellCore, - ModuleIntrinsics.GetModuleName(moduleManifestPath)); - throw workflowModuleNotSupported; -#else - // Depending on current execution policy, check the signature of Module manifest file if required. - // Reusing already created ScriptInfo object to avoid race condition when modulemanifest was not signed during first check and signed before this step. - // - scriptInfo.ValidateScriptInfo(Host); - - nestedModuleOptions.ServiceCoreAutoAdded = true; - - if (!importingModule) - { - ProcessWorkflowsToProcess(moduleBase, workflowsToProcess, new List(), - new List(), null, manifestInfo, nestedModuleOptions); - } - else - { - // Never load nested modules to the global scope. - bool oldGLobal = this.BaseGlobal; - this.BaseGlobal = false; - bool found = false; - - foreach (string workflowFileName in workflowsToProcess) - { - List wfToProcess = new List(); - wfToProcess.Add(workflowFileName); - SessionState wfSS = new SessionState(Context, true, true); - - PSModuleInfo module = new PSModuleInfo( - ModuleIntrinsics.GetModuleName(workflowFileName), workflowFileName, Context, wfSS); - wfSS.Internal.Module = module; - module.PrivateData = privateData; - module.SetModuleType(ModuleType.Workflow); - module.SetModuleBase(moduleBase); - - LoadServiceCoreModule(module, String.Empty, wfSS, nestedModuleOptions, - manifestProcessingFlags, true, out found); - - ProcessWorkflowsToProcess(moduleBase, wfToProcess, dependentWorkflows, - fixedUpAssemblyPathList, wfSS, module, nestedModuleOptions); - - // And import the members from this module into the callers context... - if (importingModule) - { - ImportModuleMembers(module, this.BasePrefix, options); - } - - // Add it to all the module tables - AddModuleToModuleTables(this.Context, this.TargetSessionState.Internal, module); - manifestInfo.AddNestedModule(module); - } - - this.BaseGlobal = oldGLobal; - } -#endif - } } catch (Exception) { @@ -3350,20 +3228,6 @@ internal PSModuleInfo LoadModuleManifest( newManifestInfo.DeclaredVariableExports = manifestInfo.DeclaredVariableExports; } - if (manifestInfo._detectedWorkflowExports != null) - { - foreach (string detectedExport in manifestInfo._detectedWorkflowExports) - { - newManifestInfo.AddDetectedWorkflowExport(detectedExport); - } - } - - if (newManifestInfo.DeclaredWorkflowExports == null || - newManifestInfo.DeclaredWorkflowExports.Count == 0) - { - newManifestInfo.DeclaredWorkflowExports = manifestInfo.DeclaredWorkflowExports; - } - // If there are types/formats entries in the ModuleToProcess use them // only if there are no entries from the manifest. The manifest entries // completely override the module's entries. @@ -3403,8 +3267,8 @@ internal PSModuleInfo LoadModuleManifest( // implicitly export functions and cmdlets. if ((ss != null) && (!ss.Internal.UseExportList)) { - ModuleIntrinsics.ExportModuleMembers(this, ss.Internal, MatchAll, - MatchAll, null, null, options.ServiceCoreAutoAdded ? s_serviceCoreAssemblyCmdlets : null); + ModuleIntrinsics.ExportModuleMembers(this, ss.Internal, functionPatterns: MatchAll, + cmdletPatterns: MatchAll, aliasPatterns: null, variablePatterns: null, doNotExportCmdlets: null); } // Export* fields in .psd1 subset Export-ModuleMember calls from ModuleToProcess=psm1 @@ -3495,9 +3359,11 @@ internal PSModuleInfo LoadModuleManifest( // the members of the manifest are canonical... ModuleIntrinsics.ExportModuleMembers(this, ss.Internal, - exportedFunctions, exportedCmdlets, - exportedAliases, exportedVariables, - options.ServiceCoreAutoAdded ? s_serviceCoreAssemblyCmdlets : null); + functionPatterns: exportedFunctions, + cmdletPatterns: exportedCmdlets, + aliasPatterns: exportedAliases, + variablePatterns: exportedVariables, + doNotExportCmdlets: null); } } @@ -3594,242 +3460,6 @@ private static void SetDeclaredDscResources(List exportedDscRes } } - private readonly string _serviceCoreAssemblyFullName = "Microsoft.Powershell.Workflow.ServiceCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"; - private readonly string _serviceCoreAssemblyShortName = "Microsoft.Powershell.Workflow.ServiceCore"; - - private PSModuleInfo LoadServiceCoreModule(PSModuleInfo parentModule, string moduleBase, SessionState ss, ImportModuleOptions nestedModuleOptions, ManifestProcessingFlags manifestProcessingFlags, bool addToParentModuleIfFound, out bool found) - { - SessionStateInternal oldSessionState = Context.EngineSessionState; - - if (ss != null) - Context.EngineSessionState = ss.Internal; - - try - { - found = false; - // Never load nested modules to the global scope. - bool oldGLobal = this.BaseGlobal; - this.BaseGlobal = false; - - PSModuleInfo nestedModule = LoadBinaryModule( - parentModule, // parentModule - false, // trySnapInName - _serviceCoreAssemblyFullName, // moduleName - null, // fileName - null, // assemblyToLoad - moduleBase, // moduleBase - ss, // SessionState - nestedModuleOptions, // ImportModuleOptions - manifestProcessingFlags, // ManifestProcessingFlags - string.Empty, // prefix: no -Prefix added for nested modules - true, // loadTypes - true, // loadFormats - out found, // found - _serviceCoreAssemblyShortName,// shortModuleName - true // disableFormatUpdates - ); - this.BaseGlobal = oldGLobal; - - // If found, add it to the parent's list of NestedModules - if (found) - { - if (addToParentModuleIfFound) - { - parentModule.AddNestedModule(nestedModule); - } - - return nestedModule; - } - else - { - string errorMessage = StringUtil.Format(Modules.ManifestMemberNotFound, _serviceCoreAssemblyFullName, "NestedModules", parentModule.Name); - FileNotFoundException fnf = new FileNotFoundException(errorMessage); - PSInvalidOperationException invalidOperation = new PSInvalidOperationException(errorMessage, fnf, "Modules_ModuleFileNotFound", ErrorCategory.ResourceUnavailable, parentModule.Name); - throw invalidOperation; - } - } - finally - { - Context.EngineSessionState = oldSessionState; - } - } - -#if !CORECLR // Workflow Not Supported On CSS - private void ProcessWorkflowsToProcess(string moduleBase, List workflowsToProcess, List dependentWorkflows, List assemblyList, SessionState ss, PSModuleInfo manifestInfo, ImportModuleOptions options) - { - // If we are actually processing - if (ss != null) - { - if (workflowsToProcess != null && workflowsToProcess.Count > 0) - { - // In ConstrainedLanguage, XAML workflows are not supported (even from a trusted FullLanguage state), - // unless they are signed in-box OS binaries. - if ((SystemPolicy.GetSystemLockdownPolicy() == SystemEnforcementMode.Enforce) || - (Context.LanguageMode == PSLanguageMode.ConstrainedLanguage)) - { - // However, this static internal property can be changed by tests that can already run a script - // in full-language mode. - if (!SystemPolicy.XamlWorkflowSupported) - { - foreach (string workflowPath in ResolveWorkflowFiles(moduleBase, workflowsToProcess)) - { - if (!SecuritySupport.IsProductBinary(workflowPath)) - { - throw new NotSupportedException(Modules.XamlWorkflowsNotSupported); - } - } - } - } - - SessionStateInternal oldSessionStateWF = Context.EngineSessionState; - PSLanguageMode? savedLanguageMode = null; - try - { - Context.EngineSessionState = ss.Internal; - - // Always run workflow import script as trusted since only signed in-box files can be imported - // on locked down machines. - if (Context.LanguageMode != PSLanguageMode.FullLanguage) - { - savedLanguageMode = Context.LanguageMode; - Context.LanguageMode = PSLanguageMode.FullLanguage; - } - - if (dependentWorkflows != null && dependentWorkflows.Count > 0) - { - ScriptBlock importWorkflow = ScriptBlock.Create(Context, - "param($files, $dependentFiles, $assemblyList) Microsoft.PowerShell.Workflow.ServiceCore\\Import-PSWorkflow -Path \"$files\" -DependentWorkflow $dependentFiles -DependentAssemblies $assemblyList -Force:$" + BaseForce - ); - - List dependentFiles = new List(ResolveDependentWorkflowFiles(moduleBase, dependentWorkflows)); - - foreach (string workflowPath in ResolveWorkflowFiles(moduleBase, workflowsToProcess)) - { - WriteVerbose(StringUtil.Format(Modules.LoadingWorkflow, workflowPath)); - importWorkflow.Invoke(workflowPath, dependentFiles.ToArray(), assemblyList.ToArray()); - } - } - else - { - ScriptBlock importWorkflow = ScriptBlock.Create(Context, - "param($files, $dependentFiles) Microsoft.PowerShell.Workflow.ServiceCore\\Import-PSWorkflow -Path \"$files\" -Force:$" + BaseForce - ); - - foreach (string workflowPath in ResolveWorkflowFiles(moduleBase, workflowsToProcess)) - { - WriteVerbose(StringUtil.Format(Modules.LoadingWorkflow, workflowPath)); - importWorkflow.Invoke(workflowPath); - } - } - - // In the case where there are only nested modules, - // the members of the manifest are canonical... - ModuleIntrinsics.ExportModuleMembers(this, ss.Internal, - MatchAll, MatchAll, MatchAll, MatchAll, - options.ServiceCoreAutoAdded ? s_serviceCoreAssemblyCmdlets : null); - } - finally - { - Context.EngineSessionState = oldSessionStateWF; - - if (savedLanguageMode != null) - { - Context.LanguageMode = savedLanguageMode.Value; - } - } - } - } - else - { - if (workflowsToProcess != null) - { - // We are in analysis - foreach (string workflowToProcess in workflowsToProcess) - { - manifestInfo.AddDetectedWorkflowExport(System.IO.Path.GetFileNameWithoutExtension(workflowToProcess)); - } - } - } - } - - private ICollection ResolveWorkflowFiles(string moduleBase, List workflowsToProcess) - { - Dictionary resolvedWorkflowsToProcess = new Dictionary(); - foreach (string workflowToProcess in workflowsToProcess) - { - if (string.Equals(System.IO.Path.GetExtension(workflowToProcess), - StringLiterals.WorkflowFileExtension, StringComparison.OrdinalIgnoreCase)) - { - string wf = workflowToProcess; - if (!Path.IsPathRooted(wf)) - { - wf = Path.Combine(moduleBase, wf); - } - - foreach (string resolvedWorkflow in Context.SessionState.Path.GetResolvedProviderPathFromProviderPath(wf, Context.ProviderNames.FileSystem)) - { - resolvedWorkflowsToProcess[resolvedWorkflow] = resolvedWorkflow; - } - } - else - { - PSInvalidOperationException invalidOperation = PSTraceSource.NewInvalidOperationException( - Modules.InvalidWorkflowExtensionDuringManifestProcessing, - workflowToProcess); - invalidOperation.SetErrorId("Modules_InvalidWorkflowExtensionDuringManifestProcessing"); - throw invalidOperation; - } - } - return resolvedWorkflowsToProcess.Values; - } - - private ICollection ResolveDependentWorkflowFiles(string moduleBase, List dependentWorkflowsToProcess) - { - Dictionary resolvedWorkflowsToProcess = new Dictionary(); - - if (dependentWorkflowsToProcess.Count == 1 && string.Equals(System.IO.Path.GetExtension(dependentWorkflowsToProcess[0]), StringLiterals.DependentWorkflowAssemblyExtension, StringComparison.OrdinalIgnoreCase)) - { - string wf = dependentWorkflowsToProcess[0]; - if (!Path.IsPathRooted(wf)) - { - wf = Path.Combine(moduleBase, wf); - } - - resolvedWorkflowsToProcess[wf] = wf; - } - else - { - foreach (string workflowToProcess in dependentWorkflowsToProcess) - { - if (string.Equals(System.IO.Path.GetExtension(workflowToProcess), - StringLiterals.WorkflowFileExtension, StringComparison.OrdinalIgnoreCase)) - { - string wf = workflowToProcess; - if (!Path.IsPathRooted(wf)) - { - wf = Path.Combine(moduleBase, wf); - } - - foreach (string resolvedWorkflow in Context.SessionState.Path.GetResolvedProviderPathFromProviderPath(wf, Context.ProviderNames.FileSystem)) - { - resolvedWorkflowsToProcess[resolvedWorkflow] = resolvedWorkflow; - } - } - else - { - PSInvalidOperationException invalidOperation = PSTraceSource.NewInvalidOperationException( - Modules.InvalidWorkflowExtensionDuringManifestProcessing, - workflowToProcess); - invalidOperation.SetErrorId("Modules_InvalidWorkflowExtensionDuringManifestProcessing"); - throw invalidOperation; - } - } - } - - return resolvedWorkflowsToProcess.Values; - } -#endif - private static void UpdateCommandCollection(List list, List patterns) where T : CommandInfo { List updated = new List(); @@ -5810,16 +5440,13 @@ internal PSModuleInfo LoadModule(PSModuleInfo parentModule, string fileName, str // implicitly export functions and cmdlets. if (!module.SessionState.Internal.UseExportList) { - ModuleIntrinsics.ExportModuleMembers(this, module.SessionState.Internal, MatchAll, - MatchAll, MatchAll, null, options.ServiceCoreAutoAdded ? ModuleCmdletBase.s_serviceCoreAssemblyCmdlets : null); + ModuleIntrinsics.ExportModuleMembers(this, module.SessionState.Internal, functionPatterns: MatchAll, + cmdletPatterns: MatchAll, aliasPatterns: MatchAll, variablePatterns: null, doNotExportCmdlets: null); } // Add it to the all module tables - if (importingModule) - { - ImportModuleMembers(module, prefix, options); - AddModuleToModuleTables(this.Context, this.TargetSessionState.Internal, module); - } + ImportModuleMembers(module, prefix, options); + AddModuleToModuleTables(this.Context, this.TargetSessionState.Internal, module); found = true; if (BaseAsCustomObject) @@ -6012,73 +5639,6 @@ internal PSModuleInfo LoadModule(PSModuleInfo parentModule, string fileName, str } } } - else if (ext.Equals(StringLiterals.WorkflowFileExtension, StringComparison.OrdinalIgnoreCase)) - { -#if CORECLR // Workflow Not Supported On CSS - PSNotSupportedException workflowModuleNotSupported = - PSTraceSource.NewNotSupportedException( - Modules.WorkflowModuleNotSupportedInPowerShellCore, - ModuleIntrinsics.GetModuleName(fileName)); - throw workflowModuleNotSupported; -#else - if (Utils.IsRunningFromSysWOW64()) - { - throw new NotSupportedException(AutomationExceptions.WorkflowDoesNotSupportWOW64); - } - - scriptInfo = GetScriptInfoForFile(fileName, out scriptName, true); - - ImportModuleOptions nestedModuleOptions = new ImportModuleOptions(); - List wfToProcess = new List(); - wfToProcess.Add(fileName); - - found = true; - - if (!importingModule) - { - module = new PSModuleInfo(ModuleIntrinsics.GetModuleName(fileName), fileName, null, null); - - ProcessWorkflowsToProcess(moduleBase, wfToProcess, new List(), new List(), null, module, nestedModuleOptions); - } - else - { - if (ss == null) - { - ss = new SessionState(Context, true, true); - } - - module = new PSModuleInfo(ModuleIntrinsics.GetModuleName(fileName), fileName, Context, ss); - ss.Internal.Module = module; - module.PrivateData = privateData; - module.SetModuleType(ModuleType.Workflow); - module.SetModuleBase(moduleBase); - - nestedModuleOptions.ServiceCoreAutoAdded = true; - - LoadServiceCoreModule(module, String.Empty, ss, nestedModuleOptions, manifestProcessingFlags, true, out found); - - ProcessWorkflowsToProcess(moduleBase, wfToProcess, new List(), new List(), ss, module, nestedModuleOptions); - - // And import the members from this module into the callers context... - if (importingModule) - { - ImportModuleMembers(module, prefix, options); - } - - // Add it to all the module tables - AddModuleToModuleTables(this.Context, this.TargetSessionState.Internal, module); - } - - if (BaseAsCustomObject) - { - WriteObject(module.AsCustomObject()); - } - else if (BasePassThru) - { - WriteObject(module); - } -#endif - } else if (ext.Equals(StringLiterals.PowerShellCmdletizationFileExtension, StringComparison.OrdinalIgnoreCase)) { found = true; @@ -6157,13 +5717,22 @@ internal PSModuleInfo LoadModule(PSModuleInfo parentModule, string fileName, str } } } + else if (ext.Equals(StringLiterals.WorkflowFileExtension, StringComparison.OrdinalIgnoreCase)) + { + found = true; + message = StringUtil.Format(Modules.WorkflowModuleNotSupported, fileName); + WriteError(new ErrorRecord( + new NotSupportedException(message), + "Modules_WorkflowModuleNotSupported", + ErrorCategory.InvalidOperation, null)); + } else { found = true; message = StringUtil.Format(Modules.InvalidModuleExtension, ext, fileName); InvalidOperationException invalidOp = new InvalidOperationException(message); ErrorRecord er = new ErrorRecord(invalidOp, "Modules_InvalidModuleExtension", - ErrorCategory.PermissionDenied, null); + ErrorCategory.InvalidOperation, null); WriteError(er); } } @@ -6453,10 +6022,6 @@ private PSModuleInfo AnalyzeScriptFile(string filename, bool force, ExecutionCon { module.AddDetectedAliasExport(commandName, null); } - if ((commandType & CommandTypes.Workflow) == CommandTypes.Workflow) - { - module.AddDetectedWorkflowExport(commandName); - } if ((commandType & CommandTypes.Function) == CommandTypes.Function) { module.AddDetectedFunctionExport(commandName); @@ -7077,15 +6642,8 @@ internal PSModuleInfo LoadBinaryModule(PSModuleInfo parentModule, bool trySnapIn WriteError(cnfe.ErrorRecord); } - // WIN8: 561104 Importing PSWorkflow module tells wrongly that their is a cmdlet Import-PSWorkflow, when there is none - // Skipping the verbose message when cmdlet name is import-psworkflow - // - if (!String.Equals(ssce.Name, "import-psworkflow", StringComparison.OrdinalIgnoreCase)) - { - string message = StringUtil.Format(ssce.CommandType == CommandTypes.Alias ? Modules.ImportingAlias : Modules.ImportingCmdlet, ssce.Name); - - WriteVerbose(message); - } + string message = StringUtil.Format(ssce.CommandType == CommandTypes.Alias ? Modules.ImportingAlias : Modules.ImportingCmdlet, ssce.Name); + WriteVerbose(message); } else { @@ -7419,12 +6977,7 @@ internal static void ImportModuleMembers( { foreach (FunctionInfo func in sourceModule.ExportedFunctions.Values) { - ImportFunctionsOrWorkflows(func, targetSessionState, sourceModule, functionPatterns, noPatternsSpecified, prefix, options, usePrefix, ref checkVerb, ref checkNoun, original2prefixedName, cmdlet, isImportModulePrivate, isFunction: true); - } - - foreach (FunctionInfo func in sourceModule.ExportedWorkflows.Values) - { - ImportFunctionsOrWorkflows(func, targetSessionState, sourceModule, functionPatterns, noPatternsSpecified, prefix, options, usePrefix, ref checkVerb, ref checkNoun, original2prefixedName, cmdlet, isImportModulePrivate, isFunction: false); + ImportFunctions(func, targetSessionState, sourceModule, functionPatterns, noPatternsSpecified, prefix, options, usePrefix, ref checkVerb, ref checkNoun, original2prefixedName, cmdlet, isImportModulePrivate, isFunction: true); } // Import any exported variables... @@ -7505,7 +7058,7 @@ internal static void ImportModuleMembers( } } - private static void ImportFunctionsOrWorkflows(FunctionInfo func, SessionStateInternal targetSessionState, PSModuleInfo sourceModule, List functionPatterns, bool noPatternsSpecified, + private static void ImportFunctions(FunctionInfo func, SessionStateInternal targetSessionState, PSModuleInfo sourceModule, List functionPatterns, bool noPatternsSpecified, string prefix, ImportModuleOptions options, bool usePrefix, ref bool checkVerb, ref bool checkNoun, Dictionary original2prefixedName, ModuleCmdletBase cmdlet, bool isImportModulePrivate, bool isFunction) { string message = null; @@ -7543,15 +7096,7 @@ private static void ImportFunctionsOrWorkflows(FunctionInfo func, SessionStateIn } ValidateCommandName(cmdlet, functionInfo.Name, sourceModule.Name, ref checkNoun, ref checkVerb); - - if (func.CommandType == CommandTypes.Workflow) - { - message = StringUtil.Format(Modules.ImportingWorkflow, prefixedName); - } - else - { - message = StringUtil.Format(Modules.ImportingFunction, prefixedName); - } + message = StringUtil.Format(Modules.ImportingFunction, prefixedName); cmdlet.WriteVerbose(message); } } diff --git a/src/System.Management.Automation/engine/Modules/PSModuleInfo.cs b/src/System.Management.Automation/engine/Modules/PSModuleInfo.cs index 8f1c3316efd..2ceefd400f3 100644 --- a/src/System.Management.Automation/engine/Modules/PSModuleInfo.cs +++ b/src/System.Management.Automation/engine/Modules/PSModuleInfo.cs @@ -575,31 +575,21 @@ public ReadOnlyDictionary GetExportedTypeDefinitions( } var res = new Dictionary(StringComparer.OrdinalIgnoreCase); - if (this.NestedModules != null) + foreach (var nestedModule in this.NestedModules) { - foreach (var nestedModule in this.NestedModules) - { - if (nestedModule == this) - { - // this is totally bizzare, but it happens for some reasons for - // Microsoft.Powershell.Workflow.ServiceCore.dll, when there is a workflow defined in a nested module. - // TODO(sevoroby): we should handle possible circular dependencies - continue; - } - - foreach (var typePairs in nestedModule.GetExportedTypeDefinitions()) - { - // The last one name wins! It's the same for command names in nested modules. - // For rootModule C with Two nested modules (A, B) the order is: A, B, C - res[typePairs.Key] = typePairs.Value; - } - } - foreach (var typePairs in _exportedTypeDefinitionsNoNested) + foreach (var typePairs in nestedModule.GetExportedTypeDefinitions()) { + // The last one name wins! It's the same for command names in nested modules. + // For rootModule C with Two nested modules (A, B) the order is: A, B, C res[typePairs.Key] = typePairs.Value; } } + foreach (var typePairs in _exportedTypeDefinitionsNoNested) + { + res[typePairs.Key] = typePairs.Value; + } + return new ReadOnlyDictionary(res); } @@ -640,8 +630,6 @@ public String Prefix internal Collection DeclaredFunctionExports = null; internal List _detectedFunctionExports = new List(); - internal List _detectedWorkflowExports = new List(); - /// /// Add function to the fixed exports list /// @@ -656,20 +644,6 @@ internal void AddDetectedFunctionExport(string name) } } - /// - /// Add workflow to the fixed exports list - /// - /// the function to add - internal void AddDetectedWorkflowExport(string name) - { - Dbg.Assert(name != null, "AddDetectedWorkflowExport should not be called with a null value"); - - if (!_detectedWorkflowExports.Contains(name)) - { - _detectedWorkflowExports.Add(name); - } - } - /// /// Lists the functions exported by this module... /// @@ -759,15 +733,6 @@ public Dictionary ExportedCommands } } - Dictionary workflows = this.ExportedWorkflows; - if (workflows != null) - { - foreach (var workflow in workflows) - { - exports[workflow.Key] = workflow.Value; - } - } - Dictionary aliases = this.ExportedAliases; if (aliases != null) { @@ -1177,48 +1142,9 @@ public Dictionary ExportedWorkflows { get { - Dictionary exportedWorkflows = new Dictionary(StringComparer.OrdinalIgnoreCase); - - if ((DeclaredWorkflowExports != null) && (DeclaredWorkflowExports.Count > 0)) - { - foreach (string fn in DeclaredWorkflowExports) - { - WorkflowInfo tempWf = new WorkflowInfo(fn, ScriptBlock.EmptyScriptBlock, context: null) { Module = this }; - exportedWorkflows[fn] = tempWf; - } - } - if ((DeclaredWorkflowExports != null) && (DeclaredWorkflowExports.Count == 0)) - { - return exportedWorkflows; - } - else - { - // If there is no session state object associated with this list, - // just return a null list of exports. This will be true if the - // module is a compiled module. - if (SessionState == null) - { - foreach (string detectedExport in _detectedWorkflowExports) - { - if (!exportedWorkflows.ContainsKey(detectedExport)) - { - WorkflowInfo tempWf = new WorkflowInfo(detectedExport, ScriptBlock.EmptyScriptBlock, context: null) { Module = this }; - exportedWorkflows[detectedExport] = tempWf; - } - } - return exportedWorkflows; - } - - foreach (WorkflowInfo wi in SessionState.Internal.ExportedWorkflows) - { - exportedWorkflows[wi.Name] = wi; - } - } - - return exportedWorkflows; + return new Dictionary(StringComparer.OrdinalIgnoreCase); } } - internal Collection DeclaredWorkflowExports = null; /// /// diff --git a/src/System.Management.Automation/help/CommandHelpProvider.cs b/src/System.Management.Automation/help/CommandHelpProvider.cs index 1de757edce3..a79d40621fd 100644 --- a/src/System.Management.Automation/help/CommandHelpProvider.cs +++ b/src/System.Management.Automation/help/CommandHelpProvider.cs @@ -124,9 +124,7 @@ private void GetModulePaths(CommandInfo commandInfo, out string moduleName, out } else if (scriptCommandInfo != null && (nestedModule.ExportedFunctions.ContainsKey(commandInfo.Name) || - nestedModule.ExportedWorkflows.ContainsKey(commandInfo.Name) || - (testWithoutPrefix && nestedModule.ExportedFunctions.ContainsKey(cmdNameWithoutPrefix)) || - (testWithoutPrefix && nestedModule.ExportedWorkflows.ContainsKey(cmdNameWithoutPrefix)))) + (testWithoutPrefix && nestedModule.ExportedFunctions.ContainsKey(cmdNameWithoutPrefix)))) { nestedModulePath = nestedModule.Path; break; diff --git a/src/System.Management.Automation/resources/AutomationExceptions.resx b/src/System.Management.Automation/resources/AutomationExceptions.resx index d83d070b07d..e48937c909d 100644 --- a/src/System.Management.Automation/resources/AutomationExceptions.resx +++ b/src/System.Management.Automation/resources/AutomationExceptions.resx @@ -195,9 +195,6 @@ Cannot generate a PowerShell object for a ScriptBlock that starts a pipeline with an expression. - - Windows PowerShell Workflow is not supported in a Windows PowerShell x86-based console. Open a Windows PowerShell x64-based console, and then try again. - The value of the using variable '$using:{0}' cannot be retrieved because it has not been set in the local session. diff --git a/src/System.Management.Automation/resources/Modules.resx b/src/System.Management.Automation/resources/Modules.resx index fbbf3f2a9a6..fad0e9f7ef1 100644 --- a/src/System.Management.Automation/resources/Modules.resx +++ b/src/System.Management.Automation/resources/Modules.resx @@ -456,9 +456,6 @@ Variables to export from this module - - Commands to export from this module as workflows - DSC resources to export from this module @@ -480,9 +477,6 @@ Minimum version of the PowerShell host required by this module - - Loading workflow {0} - HelpInfo URI of this module @@ -495,9 +489,6 @@ Because the {0} module is providing the PSDrive in the current PowerShell session, no modules were removed. Change the current PSDrive provider, and then try removing modules again. - - The workflow file name extension is not valid. The workflow file name {0} that is listed in the WorkflowsToProcess key of the module manifest does not have the required .XAML or .DLL file name extension. Edit the module manifest and correct the workflow file name. If you are using a .DLL file extension, then provide only one assembly name. - The cmdlet '{0}' was not imported because there is a member with the same name in the current scope. @@ -546,27 +537,15 @@ Running the Get-Module cmdlet against a remote computer can only list available modules. Add the ListAvailable parameter to your command, and then try again. - - The command cannot be exported as workflow '{0}'. - Exporting workflow '{0}'. - - Importing command as workflow '{0}'. - - - The command '{0}' was not imported as a workflow because there is a member with the same name in the current scope. - The '{0}' module was not imported because the '{0}' snap-in was already imported. Wildcard characters are not allowed in the member 'RequiredAssemblies' in the module manifest '{0}'. - - Exporting command as workflow '{0}'. - The value of the {0} key in {1} is {2} and the module has nested modules. When a CDXML file is the root module, the Import-Module command fails because the commands in nested modules cannot be exported. Move the CDXML file to the NestedModules key and try the command again. {0} is equal to either ModuleToProcess or RootModule @@ -592,9 +571,6 @@ A CIM provider for module discovery was not found on the CIM server. {0} {0} is a placeholder for a more detailed error message - - Cannot load the workflow. Only signed in-box XAML-based workflows or script-based workflows are supported in the current language mode. - Cannot verify the Microsoft .NET Framework version {0} because it is not included in the list of permitted versions. @@ -621,7 +597,7 @@ The specified module '{0}' was not found. Update the Name parameter to point to a valid path, and then try again. - + Cannot load the workflow module '{0}'. Workflow is not supported in PowerShell Core. diff --git a/src/System.Management.Automation/utils/PsUtils.cs b/src/System.Management.Automation/utils/PsUtils.cs index b6ede8c993f..0cf45022cac 100644 --- a/src/System.Management.Automation/utils/PsUtils.cs +++ b/src/System.Management.Automation/utils/PsUtils.cs @@ -246,10 +246,6 @@ internal static uint GetNativeThreadId() private static class NativeMethods { - // Important: - // this clone has a clone in SMA in admin\monad\src\m3p\product\ServiceCore\WorkflowCore\WorkflowRuntimeCompilation.cs - // if you are making any changes specific to this class then update the clone as well. - internal const ushort PROCESSOR_ARCHITECTURE_INTEL = 0; internal const ushort PROCESSOR_ARCHITECTURE_ARM = 5; internal const ushort PROCESSOR_ARCHITECTURE_IA64 = 6; diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 index 84e368510f8..305053bb52e 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 @@ -146,7 +146,7 @@ namespace ModuleCmdlets $psdFile = Join-Path $TESTDRIVE test.psd1 $nestedModule = Join-Path NOExistedPath Microsoft.PowerShell.Commands.Utility.dll - New-ModuleManifest -Path $psdFile -NestedModules $nestedModule + New-ModuleManifest -Path $psdFile -NestedModules $nestedModule try { $module = Import-Module $psdFile -PassThru @@ -158,7 +158,7 @@ namespace ModuleCmdlets { Remove-Module $module -ErrorAction SilentlyContinue } - + } } @@ -200,3 +200,34 @@ Describe "Import-Module should be case insensitive" -Tags 'CI' { Get-Module tESTmODULE | Should -BeNullOrEmpty } } + +Describe "Workflow .Xaml module is not supported in PSCore" -tags "Feature" { + BeforeAll { + $xamlFile = Join-Path $TestDrive "XamlTest.xaml" + New-Item -Path $xamlFile -ItemType File -Force + + $xamlRootModule = Join-Path $TestDrive "XamlRootModule" + New-Item -Path $xamlRootModule -ItemType Directory -Force + Copy-Item $xamlFile $xamlRootModule + $xamlRootModuleManifest = Join-Path $xamlRootModule "XamlRootModule.psd1" + New-ModuleManifest -Path $xamlRootModuleManifest -RootModule "XamlTest.xaml" + + $xamlNestedModule = Join-Path $TestDrive "XamlNestedModule" + New-Item -Path $xamlNestedModule -ItemType Directory -Force + Copy-Item $xamlFile $xamlNestedModule + $xamlNestedModuleManifest = Join-Path $xamlNestedModule "XamlNestedModule.psd1" + New-ModuleManifest -Path $xamlNestedModuleManifest -NestedModules "XamlTest.xaml" + } + + It "Import a XAML file directly should raise a 'NotSupported' error" { + { Import-Module $xamlFile -ErrorAction Stop } | Should -Throw -ErrorId "Modules_WorkflowModuleNotSupported,Microsoft.PowerShell.Commands.ImportModuleCommand" + } + + It "Import a module with XAML root module should raise a 'NotSupportd' error" { + { Import-Module $xamlRootModule -ErrorAction Stop } | Should -Throw -ErrorId "Modules_WorkflowModuleNotSupported,Microsoft.PowerShell.Commands.ImportModuleCommand" + } + + It "Import a module with XAML nested module should raise a 'NotSupported' error" { + { Import-Module $xamlNestedModule -ErrorAction Stop } | Should -Throw -ErrorId "Modules_WorkflowModuleNotSupported,Microsoft.PowerShell.Commands.ImportModuleCommand" + } +} diff --git a/test/powershell/engine/Module/TestModuleManifest.Tests.ps1 b/test/powershell/engine/Module/TestModuleManifest.Tests.ps1 index 14e4d07bb67..a4e62b15b0b 100644 --- a/test/powershell/engine/Module/TestModuleManifest.Tests.ps1 +++ b/test/powershell/engine/Module/TestModuleManifest.Tests.ps1 @@ -69,7 +69,7 @@ Describe "Test-ModuleManifest tests" -tags "CI" { It "module manifest containing valid processed empty rootmodule file type fails: " -TestCases ( @{rootModuleValue = "foo.cdxml"; error = "System.Xml.XmlException"}, # fails when cmdlet tries to read it as XML - @{rootModuleValue = "foo.xaml"; error = "NotSupported"} # not supported on PowerShell Core + @{rootModuleValue = "foo.xaml"; error = "Modules_WorkflowModuleNotSupported"} # not supported on PowerShell Core ) { param($rootModuleValue, $error) @@ -231,7 +231,7 @@ Describe "Test-ModuleManifest Performance bug followup" -tags "CI" { It "Test-ModuleManifest should not load unnessary modules" { $job = start-job -name "job1" -ScriptBlock {test-modulemanifest "$using:UserModulesPath\ModuleWithDependencies2\2.0\ModuleWithDependencies2.psd1" -verbose} | Wait-Job - + $verbose = $job.ChildJobs[0].Verbose.ReadAll() # Before the fix, all modules under $pshome will be imported and will be far more than 15 verbose messages. However, we cannot fix the number in case verbose message may vary. $verbose.Count | Should -BeLessThan 15