@@ -205,29 +205,39 @@ private string NormalizeProfileNameToAbsolutePath(string profileName)
205205 return Path . Combine ( _profileDir . FullName , profileName ) ;
206206 }
207207
208+ /// <summary>
209+ /// Get the path of PSScriptAnalyzer on the file system.
210+ /// </summary>
211+ /// <returns>The absolute path of the PSScriptAnalyzer module root.</returns>
208212 private static string GetModuleRootDirPath ( )
209213 {
214+ // Start from the directory containing the Rules DLL,
215+ // which may be in the module root or in a child directory (ex: coreclr)
210216 string asmDirLocation = Path . GetDirectoryName ( typeof ( CompatibilityRule ) . Assembly . Location ) ;
211- // We check our assembly location and then parent, looking for PSScriptAnalyzer.psd1,
212- // because the assembly might be in the root of the module or in a child directory (ex: coreclr).
213- // That's the base where we will find our compatibility zip file.
214- // We can't hunt for the directory 'PSScriptAnalyzer' because we may be installed in
215- // PSScriptAnalyzer/1.18.0 or PSScriptAnalyzer.
216- const string psdFile = "PSScriptAnalyzer.psd1" ;
217- string nonNormalizedRoot = asmDirLocation ;
218- string psmPath = Path . Combine ( nonNormalizedRoot , psdFile ) ;
219- if ( ! File . Exists ( psmPath ) ) {
220- nonNormalizedRoot = Path . Combine ( nonNormalizedRoot , ".." ) ;
221- psmPath = Path . Combine ( nonNormalizedRoot , psdFile ) ;
222- if ( ! File . Exists ( psmPath ) ) {
223- // Couldn't find it, give up
224- return String . Empty ;
225- }
217+
218+ // Search down the directory structure from the assembly location looking for the module root
219+ // We may be in a versioned directory ("PSScriptAnalyzer/1.18.0" vs "PSScriptAnalyzer"), so can't search that way
220+ // Instead we look for the PSSA module manifest
221+ const string manifestName = "PSScriptAnalyzer.psd1" ;
222+
223+ // Look for PSScriptAnalyzer.psd1 next to the Rules DLL
224+ string manifestPath = Path . Combine ( asmDirLocation , manifestName ) ;
225+ if ( File . Exists ( manifestPath ) )
226+ {
227+ return asmDirLocation ;
226228 }
227229
228- return Path . GetFullPath ( nonNormalizedRoot ) ;
229- }
230+ // Look for PSScriptAnalyzer.psd1 in the directory above the Rules DLL
231+ string dirUpOneLevel = Path . GetDirectoryName ( asmDirLocation ) ;
232+ manifestPath = Path . Combine ( dirUpOneLevel , manifestName ) ;
233+ if ( File . Exists ( manifestPath ) )
234+ {
235+ return dirUpOneLevel ;
236+ }
230237
238+ // Unable to find the root of the module where it should be, so we give up
239+ throw new FileNotFoundException ( "Unable to find the PSScriptAnalyzer module root" ) ;
240+ }
231241 }
232242
233243 /// <summary>
0 commit comments