From ef91ddde860a9a9ff62beab53cdfe7692d172d4f Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Tue, 8 Jun 2021 23:00:50 -0700 Subject: [PATCH 1/2] Fix the nullref in parser --- src/System.Management.Automation/engine/parser/Parser.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index d5ee729577e..3afc55e9861 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -142,6 +142,11 @@ public static ScriptBlockAst ParseInput(string input, out Token[] tokens, out Pa /// The that represents the input script file. public static ScriptBlockAst ParseInput(string input, string fileName, out Token[] tokens, out ParseError[] errors) { + if (input is null) + { + throw new ArgumentNullException(nameof(input)); + } + Parser parser = new Parser(); List tokenList = new List(); ScriptBlockAst result; From e2dc4019ac920d869ff395ef55bfff7051cbba89 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Wed, 9 Jun 2021 22:06:27 -0700 Subject: [PATCH 2/2] Clean up code regarding `AppDomain.CreateDomain` and `AppDomain.Unload` --- .../CommandCompletion/CommandCompletion.cs | 116 +++--- .../engine/CommandDiscovery.cs | 7 - .../engine/ExecutionContext.cs | 34 -- .../engine/Modules/ImportModuleCommand.cs | 1 - .../engine/Modules/ModuleCmdletBase.cs | 330 +++--------------- 5 files changed, 102 insertions(+), 386 deletions(-) diff --git a/src/System.Management.Automation/engine/CommandCompletion/CommandCompletion.cs b/src/System.Management.Automation/engine/CommandCompletion/CommandCompletion.cs index f31065080c6..730861ecb17 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CommandCompletion.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CommandCompletion.cs @@ -526,74 +526,70 @@ private static CommandCompletion CompleteInputImpl(Ast ast, Token[] tokens, IScr { var context = LocalPipeline.GetExecutionContextFromTLS(); - bool cleanupModuleAnalysisAppDomain = context.TakeResponsibilityForModuleAnalysisAppDomain(); + // First, check if a V1/V2 implementation of TabExpansion exists. If so, the user had overridden + // the built-in version, so we should continue to use theirs. + int replacementIndex = -1; + int replacementLength = -1; + List results = null; - try + if (NeedToInvokeLegacyTabExpansion(powershell)) { - // First, check if a V1/V2 implementation of TabExpansion exists. If so, the user had overridden - // the built-in version, so we should continue to use theirs. - int replacementIndex = -1; - int replacementLength = -1; - List results = null; + var inputAndCursor = GetInputAndCursorFromAst(positionOfCursor); + results = InvokeLegacyTabExpansion(powershell, inputAndCursor.Item1, inputAndCursor.Item2, false, out replacementIndex, out replacementLength); + replacementIndex += inputAndCursor.Item3; + } - if (NeedToInvokeLegacyTabExpansion(powershell)) + if (results == null || results.Count == 0) + { + /* BROKEN code commented out, fix sometime + // If we were invoked from TabExpansion2, we want to "remove" TabExpansion2 and anything it calls + // from our results. We do this by faking out the session so that TabExpansion2 isn't anywhere to be found. + MutableTuple tupleForFrameToSkipPast = null; + foreach (var stackEntry in context.Debugger.GetCallStack()) { - var inputAndCursor = GetInputAndCursorFromAst(positionOfCursor); - results = InvokeLegacyTabExpansion(powershell, inputAndCursor.Item1, inputAndCursor.Item2, false, out replacementIndex, out replacementLength); - replacementIndex += inputAndCursor.Item3; + dynamic stackEntryAsPSObj = PSObject.AsPSObject(stackEntry); + if (stackEntryAsPSObj.Command.Equals("TabExpansion2", StringComparison.OrdinalIgnoreCase)) + { + tupleForFrameToSkipPast = stackEntry.FunctionContext._localsTuple; + break; + } } - if (results == null || results.Count == 0) + SessionStateScope scopeToRestore = null; + if (tupleForFrameToSkipPast != null) { - /* BROKEN code commented out, fix sometime - // If we were invoked from TabExpansion2, we want to "remove" TabExpansion2 and anything it calls - // from our results. We do this by faking out the session so that TabExpansion2 isn't anywhere to be found. - MutableTuple tupleForFrameToSkipPast = null; - foreach (var stackEntry in context.Debugger.GetCallStack()) + // Find this tuple in the scope stack. + scopeToRestore = context.EngineSessionState.CurrentScope; + var scope = context.EngineSessionState.CurrentScope; + while (scope != null && scope.LocalsTuple != tupleForFrameToSkipPast) { - dynamic stackEntryAsPSObj = PSObject.AsPSObject(stackEntry); - if (stackEntryAsPSObj.Command.Equals("TabExpansion2", StringComparison.OrdinalIgnoreCase)) - { - tupleForFrameToSkipPast = stackEntry.FunctionContext._localsTuple; - break; - } + scope = scope.Parent; } - SessionStateScope scopeToRestore = null; - if (tupleForFrameToSkipPast != null) + if (scope != null) { - // Find this tuple in the scope stack. - scopeToRestore = context.EngineSessionState.CurrentScope; - var scope = context.EngineSessionState.CurrentScope; - while (scope != null && scope.LocalsTuple != tupleForFrameToSkipPast) - { - scope = scope.Parent; - } - - if (scope != null) - { - context.EngineSessionState.CurrentScope = scope.Parent; - } + context.EngineSessionState.CurrentScope = scope.Parent; } + } - try - { - */ - var completionAnalysis = new CompletionAnalysis(ast, tokens, positionOfCursor, options); - results = completionAnalysis.GetResults(powershell, out replacementIndex, out replacementLength); - /* - } - finally + try + { + */ + var completionAnalysis = new CompletionAnalysis(ast, tokens, positionOfCursor, options); + results = completionAnalysis.GetResults(powershell, out replacementIndex, out replacementLength); + /* + } + finally + { + if (scopeToRestore != null) { - if (scopeToRestore != null) - { - context.EngineSessionState.CurrentScope = scopeToRestore; - } + context.EngineSessionState.CurrentScope = scopeToRestore; } - */ } + */ + } - var completionResults = results ?? EmptyCompletionResult; + var completionResults = results ?? EmptyCompletionResult; #if LEGACYTELEMETRY // no telemetry here. We don't capture tab completion performance. @@ -601,19 +597,11 @@ private static CommandCompletion CompleteInputImpl(Ast ast, Token[] tokens, IScr TelemetryAPI.ReportTabCompletionTelemetry(sw.ElapsedMilliseconds, completionResults.Count, completionResults.Count > 0 ? completionResults[0].ResultType : CompletionResultType.Text); #endif - return new CommandCompletion( - new Collection(completionResults), - -1, - replacementIndex, - replacementLength); - } - finally - { - if (cleanupModuleAnalysisAppDomain) - { - context.ReleaseResponsibilityForModuleAnalysisAppDomain(); - } - } + return new CommandCompletion( + new Collection(completionResults), + -1, + replacementIndex, + replacementLength); } } diff --git a/src/System.Management.Automation/engine/CommandDiscovery.cs b/src/System.Management.Automation/engine/CommandDiscovery.cs index ee6e5943800..fb9f9f5b580 100644 --- a/src/System.Management.Automation/engine/CommandDiscovery.cs +++ b/src/System.Management.Automation/engine/CommandDiscovery.cs @@ -1053,7 +1053,6 @@ private static CommandInfo TryModuleAutoDiscovery(string commandName, if (etwEnabled) CommandDiscoveryEventSource.Log.ModuleAutoDiscoveryStart(commandName); CommandInfo result = null; - bool cleanupModuleAnalysisAppDomain = false; try { // If commandName had a slash, it was module-qualified or path-qualified. @@ -1076,8 +1075,6 @@ private static CommandInfo TryModuleAutoDiscovery(string commandName, discoveryTracer.WriteLine("Executing non module-qualified search: {0}", commandName); context.CommandDiscovery.RegisterLookupCommandInfoAction("ActiveModuleSearch", commandName); - cleanupModuleAnalysisAppDomain = context.TakeResponsibilityForModuleAnalysisAppDomain(); - // Get the available module files, preferring modules from $PSHOME so that user modules don't // override system modules during auto-loading if (etwEnabled) CommandDiscoveryEventSource.Log.SearchingForModuleFilesStart(); @@ -1142,10 +1139,6 @@ private static CommandInfo TryModuleAutoDiscovery(string commandName, finally { context.CommandDiscovery.UnregisterLookupCommandInfoAction("ActiveModuleSearch", commandName); - if (cleanupModuleAnalysisAppDomain) - { - context.ReleaseResponsibilityForModuleAnalysisAppDomain(); - } } if (etwEnabled) CommandDiscoveryEventSource.Log.ModuleAutoDiscoveryStop(commandName); diff --git a/src/System.Management.Automation/engine/ExecutionContext.cs b/src/System.Management.Automation/engine/ExecutionContext.cs index 9b2255f372c..cfcc417de4a 100644 --- a/src/System.Management.Automation/engine/ExecutionContext.cs +++ b/src/System.Management.Automation/engine/ExecutionContext.cs @@ -205,40 +205,6 @@ internal bool ShouldTraceStatement /// internal string ModuleBeingProcessed { get; set; } - private bool _responsibilityForModuleAnalysisAppDomainOwned; - - internal bool TakeResponsibilityForModuleAnalysisAppDomain() - { - if (_responsibilityForModuleAnalysisAppDomainOwned) - { - return false; - } - - Diagnostics.Assert(AppDomainForModuleAnalysis == null, "Invalid module analysis app domain state"); - _responsibilityForModuleAnalysisAppDomainOwned = true; - return true; - } - - internal void ReleaseResponsibilityForModuleAnalysisAppDomain() - { - Diagnostics.Assert(_responsibilityForModuleAnalysisAppDomainOwned, "Invalid module analysis app domain state"); - - if (AppDomainForModuleAnalysis != null) - { - AppDomain.Unload(AppDomainForModuleAnalysis); - AppDomainForModuleAnalysis = null; - } - - _responsibilityForModuleAnalysisAppDomainOwned = false; - } - - /// - /// The AppDomain currently being used for module analysis. It should only be created if needed, - /// but various callers need to take responsibility for unloading the domain via - /// the TakeResponsibilityForModuleAnalysisAppDomain. - /// - internal AppDomain AppDomainForModuleAnalysis { get; set; } - /// /// Authorization manager for this runspace. /// diff --git a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs index 024c7a7856e..2cbb30bcb00 100644 --- a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs +++ b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs @@ -589,7 +589,6 @@ private void ImportModule_ViaAssembly(ImportModuleOptions importModuleOptions, A if (!moduleLoaded) { PSModuleInfo module = LoadBinaryModule( - trySnapInName: false, moduleName: null, fileName: null, suppliedAssembly, diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index cd32fda145b..d8ed2bc6537 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -878,7 +878,6 @@ private PSModuleInfo LoadModuleNamedInManifest(PSModuleInfo parentModule, Module // At this point, we are already exhaust all possible ways to load the nested module. The last option is to load it as a binary module/snapin. module = LoadBinaryModule( parentModule, - trySnapInName: true, moduleSpecification.Name, fileName: null, assemblyToLoad: null, @@ -1056,35 +1055,27 @@ private IEnumerable GetModuleForNames(List names, bool all { IEnumerable allModules = null; HashSet modulePathSet = new HashSet(StringComparer.OrdinalIgnoreCase); - bool cleanupModuleAnalysisAppDomain = Context.TakeResponsibilityForModuleAnalysisAppDomain(); - try + foreach (string path in ModuleIntrinsics.GetModulePath(false, Context)) { - foreach (string path in ModuleIntrinsics.GetModulePath(false, Context)) - { - string uniquePath = path.TrimEnd(Utils.Separators.Directory); + string uniquePath = path.TrimEnd(Utils.Separators.Directory); - // Ignore repeated module path. - if (!modulePathSet.Add(uniquePath)) { continue; } + // Ignore repeated module path. + if (!modulePathSet.Add(uniquePath)) + { + continue; + } - try - { - IEnumerable modulesFound = GetModulesFromOneModulePath( - names, uniquePath, all, refresh).OrderBy(static m => m.Name); - allModules = allModules == null ? modulesFound : allModules.Concat(modulesFound); - } - catch (Exception e) when (e is IOException || e is UnauthorizedAccessException) - { - // ignore directories that can't be accessed - continue; - } + try + { + IEnumerable modulesFound = GetModulesFromOneModulePath( + names, uniquePath, all, refresh).OrderBy(static m => m.Name); + allModules = allModules == null ? modulesFound : allModules.Concat(modulesFound); } - } - finally - { - if (cleanupModuleAnalysisAppDomain) + catch (Exception e) when (e is IOException || e is UnauthorizedAccessException) { - Context.ReleaseResponsibilityForModuleAnalysisAppDomain(); + // ignore directories that can't be accessed + continue; } } @@ -5892,7 +5883,6 @@ internal PSModuleInfo LoadModule(PSModuleInfo parentModule, string fileName, str ext.Equals(StringLiterals.PowerShellILExecutableExtension, StringComparison.OrdinalIgnoreCase)) { module = LoadBinaryModule( - trySnapInName: false, ModuleIntrinsics.GetModuleName(fileName), fileName, assemblyToLoad: null, @@ -6117,7 +6107,6 @@ private static void ClearAnalysisCaches() private static readonly Dictionary> s_binaryAnalysisCache = new Dictionary>(); -#if CORECLR /// /// Analyze the module assembly to find out all cmdlets and aliases defined in that assembly. /// @@ -6157,155 +6146,6 @@ private static BinaryAnalysisResult GetCmdletsFromBinaryModuleImplementation(str return resultToReturn; } -#else - /// - /// Analyze the module assembly to find out all cmdlets and aliases defined in that assembly. - /// - private BinaryAnalysisResult GetCmdletsFromBinaryModuleImplementation(string path, ManifestProcessingFlags manifestProcessingFlags, out Version assemblyVersion) - { - Tuple tuple = null; - - lock (s_lockObject) - { - s_binaryAnalysisCache.TryGetValue(path, out tuple); - } - - if (tuple != null) - { - assemblyVersion = tuple.Item2; - return tuple.Item1; - } - - assemblyVersion = new Version("0.0.0.0"); - - bool cleanupModuleAnalysisAppDomain = false; - AppDomain tempDomain = Context.AppDomainForModuleAnalysis; - if (tempDomain == null) - { - cleanupModuleAnalysisAppDomain = Context.TakeResponsibilityForModuleAnalysisAppDomain(); - tempDomain = Context.AppDomainForModuleAnalysis = AppDomain.CreateDomain("ReflectionDomain"); - } - - try - { - // create temp appdomain if one is not passed in - tempDomain.SetData("PathToProcess", path); - tempDomain.SetData("IsModuleLoad", 0 != (manifestProcessingFlags & ManifestProcessingFlags.LoadElements)); - - // reset DetectedCmdlets and AssemblyVersion from previous invocation - tempDomain.SetData("DetectedCmdlets", null); - tempDomain.SetData("DetectedAliases", null); - tempDomain.SetData("AssemblyVersion", assemblyVersion); - - tempDomain.DoCallBack(AnalyzeSnapinDomainHelper); - List detectedCmdlets = (List)tempDomain.GetData("DetectedCmdlets"); - List> detectedAliases = (List>)tempDomain.GetData("DetectedAliases"); - assemblyVersion = (Version)tempDomain.GetData("AssemblyVersion"); - - if ((detectedCmdlets.Count == 0) && (System.IO.Path.IsPathRooted(path))) - { - // If we couldn't load it from a file, try loading from the GAC - string assemblyname = Path.GetFileName(path); - BinaryAnalysisResult gacResult = GetCmdletsFromBinaryModuleImplementation(assemblyname, manifestProcessingFlags, out assemblyVersion); - detectedCmdlets = gacResult.DetectedCmdlets; - detectedAliases = gacResult.DetectedAliases; - } - - BinaryAnalysisResult result = new BinaryAnalysisResult(); - result.DetectedCmdlets = detectedCmdlets; - result.DetectedAliases = detectedAliases; - - lock (s_lockObject) - { - s_binaryAnalysisCache[path] = Tuple.Create(result, assemblyVersion); - } - - return result; - } - finally - { - if (cleanupModuleAnalysisAppDomain) - { - Context.ReleaseResponsibilityForModuleAnalysisAppDomain(); - } - } - } - - private static void AnalyzeSnapinDomainHelper() - { - string path = (string)AppDomain.CurrentDomain.GetData("PathToProcess"); - bool isModuleLoad = (bool)AppDomain.CurrentDomain.GetData("IsModuleLoad"); - Dictionary cmdlets = null; - Dictionary> aliases = null; - Dictionary providers = null; - string throwAwayHelpFile = null; - Version assemblyVersion = new Version("0.0.0.0"); - - try - { - Assembly assembly = null; - - try - { - // If this is a fully-qualified search, load it from the file - if (Path.IsPathRooted(path)) - { - assembly = InitialSessionState.LoadAssemblyFromFile(path); - } - else - { - // Otherwise, load it from the GAC - Exception ignored = null; - assembly = ExecutionContext.LoadAssembly(path, null, out ignored); - } - - if (assembly != null) - { - assemblyVersion = GetAssemblyVersionNumber(assembly); - } - } - // Catch-all OK, analyzing user code. - catch (Exception) - { - } - - if (assembly != null) - { - PSSnapInHelpers.AnalyzePSSnapInAssembly(assembly, assembly.Location, null, null, isModuleLoad, out cmdlets, out aliases, out providers, out throwAwayHelpFile); - } - } - // Catch-all OK, analyzing user code. - catch (Exception) - { - } - - List detectedCmdlets = new List(); - List> detectedAliases = new List>(); - - if (cmdlets != null) - { - foreach (SessionStateCmdletEntry cmdlet in cmdlets.Values) - { - detectedCmdlets.Add(cmdlet.Name); - } - } - - if (aliases != null) - { - foreach (List aliasList in aliases.Values) - { - foreach (SessionStateAliasEntry alias in aliasList) - { - detectedAliases.Add(new Tuple(alias.Name, alias.Definition)); - } - } - } - - AppDomain.CurrentDomain.SetData("DetectedCmdlets", detectedCmdlets); - AppDomain.CurrentDomain.SetData("DetectedAliases", detectedAliases); - AppDomain.CurrentDomain.SetData("AssemblyVersion", assemblyVersion); - } -#endif // Analyzes a script module implementation for its exports. private static readonly Dictionary s_scriptAnalysisCache = new Dictionary(); @@ -6524,7 +6364,6 @@ private PSModuleInfo AnalyzeScriptFile(string filename, bool force, ExecutionCon /// /// Load a binary module. A binary module is an assembly that should contain cmdlets. /// - /// If true, then the registered snapins will also be searched when loading. /// The name of the snapin or assembly to load. /// The path to the assembly to load. /// The assembly to load so no lookup need be done. @@ -6542,7 +6381,6 @@ private PSModuleInfo AnalyzeScriptFile(string filename, bool force, ExecutionCon /// Sets this to true if an assembly was found. /// THe module info object that was created... internal PSModuleInfo LoadBinaryModule( - bool trySnapInName, string moduleName, string fileName, Assembly assemblyToLoad, @@ -6557,7 +6395,6 @@ internal PSModuleInfo LoadBinaryModule( { return LoadBinaryModule( parentModule: null, - trySnapInName, moduleName, fileName, assemblyToLoad, @@ -6577,7 +6414,6 @@ internal PSModuleInfo LoadBinaryModule( /// Load a binary module. A binary module is an assembly that should contain cmdlets. /// /// The parent module for which this module is a nested module. - /// If true, then the registered snapins will also be searched when loading. /// The name of the snapin or assembly to load. /// The path to the assembly to load. /// The assembly to load so no lookup need be done. @@ -6598,7 +6434,6 @@ internal PSModuleInfo LoadBinaryModule( /// THe module info object that was created... internal PSModuleInfo LoadBinaryModule( PSModuleInfo parentModule, - bool trySnapInName, string moduleName, string fileName, Assembly assemblyToLoad, @@ -6624,7 +6459,6 @@ internal PSModuleInfo LoadBinaryModule( List> detectedAliases = null; Assembly assembly = null; Exception error = null; - bool importSuccessful = false; string modulePath = string.Empty; Version assemblyVersion = new Version(0, 0, 0, 0); var importingModule = (manifestProcessingFlags & ManifestProcessingFlags.LoadElements) != 0; @@ -6675,114 +6509,50 @@ internal PSModuleInfo LoadBinaryModule( } } } - else + else if (importingModule) { - // Avoid trying to import a PowerShell assembly as Snapin as it results in PSArgumentException - if ((moduleName != null) && Utils.IsPowerShellAssembly(moduleName)) - { - trySnapInName = false; - } + assembly = Context.AddAssembly(moduleName, fileName, out error); - if (trySnapInName && PSSnapInInfo.IsPSSnapinIdValid(moduleName)) + if (assembly == null) { - PSSnapInInfo snapin = null; + if (error != null) + throw error; -#if !CORECLR - // Avoid trying to load SnapIns with Import-Module - PSSnapInException warning; - try - { - if (importingModule) - { - snapin = iss.ImportPSSnapIn(moduleName, out warning); - } - } - catch (PSArgumentException) - { - // BUGBUG - brucepay - probably want to have a verbose message here... - } -#endif - - if (snapin != null) - { - importSuccessful = true; - if (string.IsNullOrEmpty(fileName)) - modulePath = snapin.AbsoluteModulePath; - else - modulePath = fileName; - assemblyVersion = snapin.Version; - // If we're not supposed to load the types files from the snapin - // clear the iss member - if (!loadTypes) - { - iss.Types.Reset(); - } - // If we're not supposed to load the format files from the snapin, - // clear the iss member - if (!loadFormats) - { - iss.Formats.Reset(); - } - - foreach (var a in ClrFacade.GetAssemblies()) - { - if (a.GetName().FullName.Equals(snapin.AssemblyName, StringComparison.Ordinal)) - { - assembly = a; - break; - } - } - } + found = false; + return null; } - if (!importSuccessful) - { - if (importingModule) - { - assembly = Context.AddAssembly(moduleName, fileName, out error); - - if (assembly == null) - { - if (error != null) - throw error; + assemblyVersion = GetAssemblyVersionNumber(assembly); - found = false; - return null; - } - - assemblyVersion = GetAssemblyVersionNumber(assembly); - - if (string.IsNullOrEmpty(fileName)) - modulePath = assembly.Location; - else - modulePath = fileName; - - // Passing module as a parameter here so that the providers can have the module property populated. - // For engine providers, the module should point to top-level module name - // For FileSystem, the module is Microsoft.PowerShell.Core and not System.Management.Automation - if (parentModule != null && InitialSessionState.IsEngineModule(parentModule.Name)) - { - iss.ImportCmdletsFromAssembly(assembly, parentModule); - } - else - { - iss.ImportCmdletsFromAssembly(assembly, null); - } - } - else - { - string binaryPath = fileName; - modulePath = fileName; - if (binaryPath == null) - { - binaryPath = System.IO.Path.Combine(moduleBase, moduleName); - } + if (string.IsNullOrEmpty(fileName)) + modulePath = assembly.Location; + else + modulePath = fileName; - BinaryAnalysisResult analysisResult = GetCmdletsFromBinaryModuleImplementation(binaryPath, manifestProcessingFlags, out assemblyVersion); - detectedCmdlets = analysisResult.DetectedCmdlets; - detectedAliases = analysisResult.DetectedAliases; - } + // Passing module as a parameter here so that the providers can have the module property populated. + // For engine providers, the module should point to top-level module name + // For FileSystem, the module is Microsoft.PowerShell.Core and not System.Management.Automation + if (parentModule != null && InitialSessionState.IsEngineModule(parentModule.Name)) + { + iss.ImportCmdletsFromAssembly(assembly, parentModule); + } + else + { + iss.ImportCmdletsFromAssembly(assembly, null); + } + } + else + { + string binaryPath = fileName; + modulePath = fileName; + if (binaryPath == null) + { + binaryPath = System.IO.Path.Combine(moduleBase, moduleName); } + + BinaryAnalysisResult analysisResult = GetCmdletsFromBinaryModuleImplementation(binaryPath, manifestProcessingFlags, out assemblyVersion); + detectedCmdlets = analysisResult.DetectedCmdlets; + detectedAliases = analysisResult.DetectedAliases; } found = true;