44
55using System ;
66using System . IO ;
7+ using System . Linq ;
78using System . Reflection ;
9+ #if NET46
10+ using Microsoft . VisualStudio . Setup . Configuration ;
11+ #endif
812
913namespace Microsoft . Build . Utilities . ProjectCreation
1014{
@@ -17,21 +21,15 @@ public static class MSBuildAssemblyResolver
1721 ( ) =>
1822 {
1923 string visualStudioDirectory ;
20- string msbuildVersionDirectory = Environment . GetEnvironmentVariable ( "VISUALSTUDIOVERSION" ) ?? "15.0" ;
21-
22- if ( Version . TryParse ( msbuildVersionDirectory , out Version visualStudioVersion ) && visualStudioVersion . Major >= 16 )
23- {
24- msbuildVersionDirectory = "Current" ;
25- }
2624
2725 if ( ! String . IsNullOrWhiteSpace ( visualStudioDirectory = Environment . GetEnvironmentVariable ( "VSINSTALLDIR" ) ) )
2826 {
29- return Path . Combine ( visualStudioDirectory , "MSBuild" , msbuildVersionDirectory , "Bin" ) ;
27+ return Path . Combine ( visualStudioDirectory , "MSBuild" , GetMSBuildVersionDirectory ( Environment . GetEnvironmentVariable ( "VISUALSTUDIOVERSION" ) ?? "15.0" ) , "Bin" ) ;
3028 }
3129
3230 if ( ! String . IsNullOrWhiteSpace ( visualStudioDirectory = Environment . GetEnvironmentVariable ( "VSAPPIDDIR" ) ) )
3331 {
34- return Path . GetFullPath ( Path . Combine ( visualStudioDirectory , ".." , ".." , "MSBuild" , msbuildVersionDirectory , "Bin" ) ) ;
32+ return Path . GetFullPath ( Path . Combine ( visualStudioDirectory , ".." , ".." , "MSBuild" , GetMSBuildVersionDirectory ( Environment . GetEnvironmentVariable ( "VISUALSTUDIOVERSION" ) ?? "15.0" ) , "Bin" ) ) ;
3533 }
3634
3735 foreach ( string path in ( Environment . GetEnvironmentVariable ( "PATH" ) ?? String . Empty ) . Split ( PathSplitChars , StringSplitOptions . RemoveEmptyEntries ) )
@@ -41,7 +39,12 @@ public static class MSBuildAssemblyResolver
4139 return path ;
4240 }
4341 }
44-
42+ #if NET46
43+ if ( ! String . IsNullOrWhiteSpace ( visualStudioDirectory = MSBuildAssemblyResolver . GetPathOfFirstInstalledVisualStudioInstance ( ) ) )
44+ {
45+ return visualStudioDirectory ;
46+ }
47+ #endif
4548 return null ;
4649 } ,
4750 isThreadSafe : true ) ;
@@ -63,6 +66,11 @@ public static Assembly AssemblyResolve(object sender, ResolveEventArgs args)
6366 {
6467 AssemblyName assemblyName = new AssemblyName ( args . Name ) ;
6568
69+ if ( MSBuildPath == null )
70+ {
71+ return null ;
72+ }
73+
6674 FileInfo fileInfo = new FileInfo ( Path . Combine ( MSBuildPath , $ "{ assemblyName . Name } .dll") ) ;
6775
6876 if ( ! fileInfo . Exists )
@@ -72,5 +80,58 @@ public static Assembly AssemblyResolve(object sender, ResolveEventArgs args)
7280
7381 return ! assemblyName . FullName . Equals ( AssemblyName . GetAssemblyName ( fileInfo . FullName ) . FullName ) ? null : Assembly . LoadFrom ( fileInfo . FullName ) ;
7482 }
83+
84+ private static string GetMSBuildVersionDirectory ( string version )
85+ {
86+ if ( Version . TryParse ( version , out Version visualStudioVersion ) && visualStudioVersion . Major >= 16 )
87+ {
88+ return "Current" ;
89+ }
90+
91+ return version ;
92+ }
93+
94+ #if NET46
95+ private static string GetPathOfFirstInstalledVisualStudioInstance ( )
96+ {
97+ Tuple < Version , string > highestVersion = null ;
98+
99+ try
100+ {
101+ IEnumSetupInstances setupInstances = new SetupConfiguration ( ) . EnumAllInstances ( ) ;
102+
103+ ISetupInstance [ ] instances = new ISetupInstance [ 1 ] ;
104+
105+ for ( setupInstances . Next ( 1 , instances , out int fetched ) ; fetched > 0 ; setupInstances . Next ( 1 , instances , out fetched ) )
106+ {
107+ ISetupInstance2 instance = ( ISetupInstance2 ) instances . First ( ) ;
108+
109+ if ( instance . GetState ( ) == InstanceState . Complete )
110+ {
111+ string installationPath = instance . GetInstallationPath ( ) ;
112+
113+ if ( ! String . IsNullOrWhiteSpace ( installationPath ) && Version . TryParse ( instance . GetInstallationVersion ( ) , out Version version ) )
114+ {
115+ if ( highestVersion == null || version > highestVersion . Item1 )
116+ {
117+ highestVersion = new Tuple < Version , string > ( version , installationPath ) ;
118+ }
119+ }
120+ }
121+ }
122+
123+ if ( highestVersion != null )
124+ {
125+ return Path . Combine ( highestVersion . Item2 , "MSBuild" , GetMSBuildVersionDirectory ( $ "{ highestVersion . Item1 . Major } .{ highestVersion . Item1 . Minor } ") , "Bin" ) ;
126+ }
127+ }
128+ catch
129+ {
130+ // Ignored
131+ }
132+
133+ return null ;
134+ }
135+ #endif
75136 }
76137}
0 commit comments