From fd81167857bbde19b3fcd07113b0b0af1bd0c7ca Mon Sep 17 00:00:00 2001 From: David Wilson Date: Mon, 19 Dec 2016 11:06:03 -0800 Subject: [PATCH] Fix #325: Module dependency loading should pick latest module version This change fixes an issue with the loading of both the PSScriptAnalyzer and Plaster modules. We were simply using Import-Module without specifying a version to be loaded. Apparently PowerShell prioritizes the PSModulePath order over the module version order so there are instances where an older version of one of these module will be loaded even though a newer version is available at a different location on the machine. This change adds extra logic to sort the list of returned modules so that the latest version of the module is always loaded. --- .../Analysis/AnalysisService.cs | 16 +++++++--- .../Templates/TemplateService.cs | 29 ++++++++++++++----- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/PowerShellEditorServices/Analysis/AnalysisService.cs b/src/PowerShellEditorServices/Analysis/AnalysisService.cs index 268fcd41d..d2318c446 100644 --- a/src/PowerShellEditorServices/Analysis/AnalysisService.cs +++ b/src/PowerShellEditorServices/Analysis/AnalysisService.cs @@ -179,10 +179,18 @@ private void FindPSScriptAnalyzer() { ps.Runspace = this.analysisRunspace; - var modules = ps.AddCommand("Get-Module") - .AddParameter("List") - .AddParameter("Name", "PSScriptAnalyzer") - .Invoke(); + ps.AddCommand("Get-Module") + .AddParameter("ListAvailable") + .AddParameter("Name", "PSScriptAnalyzer"); + + ps.AddCommand("Sort-Object") + .AddParameter("Descending") + .AddParameter("Property", "Version"); + + ps.AddCommand("Select-Object") + .AddParameter("First", 1); + + var modules = ps.Invoke(); var psModule = modules == null ? null : modules.FirstOrDefault(); if (psModule != null) diff --git a/src/PowerShellEditorServices/Templates/TemplateService.cs b/src/PowerShellEditorServices/Templates/TemplateService.cs index d0114d9ed..619972796 100644 --- a/src/PowerShellEditorServices/Templates/TemplateService.cs +++ b/src/PowerShellEditorServices/Templates/TemplateService.cs @@ -52,17 +52,29 @@ public async Task ImportPlasterIfInstalled() if (!this.isPlasterInstalled.HasValue) { PSCommand psCommand = new PSCommand(); - psCommand.AddCommand("Get-Module"); - psCommand.AddParameter("ListAvailable"); - psCommand.AddParameter("Name", "Plaster"); + + psCommand + .AddCommand("Get-Module") + .AddParameter("ListAvailable") + .AddParameter("Name", "Plaster"); + + psCommand + .AddCommand("Sort-Object") + .AddParameter("Descending") + .AddParameter("Property", "Version"); + + psCommand + .AddCommand("Select-Object") + .AddParameter("First", 1); Logger.Write(LogLevel.Verbose, "Checking if Plaster is installed..."); var getResult = - await this.powerShellContext.ExecuteCommand( + await this.powerShellContext.ExecuteCommand( psCommand, false, false); - this.isPlasterInstalled = getResult.Any(); + PSObject moduleObject = getResult.First(); + this.isPlasterInstalled = moduleObject != null; string installedQualifier = this.isPlasterInstalled.Value ? string.Empty : "not "; @@ -77,9 +89,10 @@ await this.powerShellContext.ExecuteCommand( Logger.Write(LogLevel.Verbose, "Loading Plaster..."); psCommand = new PSCommand(); - psCommand.AddCommand("Import-Module"); - psCommand.AddParameter("Name", "Plaster"); - psCommand.AddParameter("PassThru"); + psCommand + .AddCommand("Import-Module") + .AddParameter("ModuleInfo", (PSModuleInfo)moduleObject.ImmediateBaseObject) + .AddParameter("PassThru"); var importResult = await this.powerShellContext.ExecuteCommand(