1
1
2
- using Microsoft . VisualStudio . Setup . Configuration ;
3
- using System . Runtime . InteropServices ;
4
-
5
2
namespace BuildScripts ;
6
3
7
4
[ TaskName ( "Build Windows" ) ]
@@ -52,7 +49,7 @@ private bool IsOnPATH(string process)
52
49
if ( ! process . EndsWith ( ".exe" ) )
53
50
process += ".exe" ;
54
51
55
- // check if process exist on PATH env
52
+ // Check if process exist on PATH env
56
53
57
54
var split = Environment . GetEnvironmentVariable ( "PATH" ) ? . Split ( ';' ) ;
58
55
if ( split != null )
@@ -70,86 +67,29 @@ private bool IsOnPATH(string process)
70
67
71
68
private string GetVisualStudioPath ( )
72
69
{
73
- // This code to retrieve where Visual Studio is installed is adapted from
74
- // https://github.com/microsoft/MSBuildLocator
75
- // Surprisingly, this package has code to retrieve a VS installation but
76
- // this feature is disabled from the public nuget... so adapting it from source
77
-
78
- // This will only detect Visual Studio 2015 and above
79
-
80
- string path = string . Empty ;
81
- Version version = new Version ( ) ;
82
-
83
- try
70
+ // We can use vswhere.exe which ships with VS2017 and later.
71
+ // Microsoft guarantees that it is always installed in %ProgramFiles(x86)%\Microsoft Visual Studio\Installer
72
+
73
+ System . Diagnostics . Process process = new System . Diagnostics . Process ( ) ;
74
+ process . StartInfo . FileName = System . IO . Path . Combine ( Environment . ExpandEnvironmentVariables ( "%ProgramFiles(x86)%" ) , "Microsoft Visual Studio\\ Installer\\ vswhere.exe" ) ;
75
+ process . StartInfo . Arguments = "-latest" ;
76
+ process . StartInfo . UseShellExecute = false ;
77
+ process . StartInfo . RedirectStandardOutput = true ;
78
+ process . StartInfo . CreateNoWindow = true ;
79
+ process . Start ( ) ;
80
+
81
+ string result = process . StandardOutput . ReadToEnd ( ) ;
82
+
83
+ if ( ! string . IsNullOrEmpty ( result ) )
84
84
{
85
- // This code is not obvious. See the sample (link above) for reference.
86
- var query = ( ISetupConfiguration2 ) GetQuery ( ) ;
87
- var e = query . EnumAllInstances ( ) ;
88
-
89
- int fetched ;
90
- var instances = new ISetupInstance [ 1 ] ;
91
- do
85
+ var lines = result . Split ( "\r \n " ) ;
86
+ foreach ( var line in lines )
92
87
{
93
- // Call e.Next to query for the next instance (single item or nothing returned).
94
- e . Next ( 1 , instances , out fetched ) ;
95
- if ( fetched <= 0 ) continue ;
96
-
97
- var instance = ( ISetupInstance2 ) instances [ 0 ] ;
98
- InstanceState state = instance . GetState ( ) ;
99
-
100
- // If the install was complete
101
- if ( state == InstanceState . Complete ||
102
- ( state . HasFlag ( InstanceState . Registered ) && state . HasFlag ( InstanceState . NoRebootRequired ) ) )
103
- {
104
- if ( ! Version . TryParse ( instance . GetInstallationVersion ( ) , out var current ) )
105
- continue ;
106
-
107
- // We want the highest version installed
108
- if ( current <= version )
109
- continue ;
110
-
111
- version = current ;
112
- path = instance . GetInstallationPath ( ) ;
113
- }
88
+ if ( line . StartsWith ( "installationPath: " ) )
89
+ return line . Substring ( 18 ) ;
114
90
}
115
- while ( fetched > 0 ) ;
116
- }
117
- catch ( COMException )
118
- {
119
- }
120
- catch ( DllNotFoundException )
121
- {
122
- // This is OK, VS "15" or greater likely not installed.
123
91
}
124
92
125
- return path ;
93
+ return string . Empty ;
126
94
}
127
-
128
- private static ISetupConfiguration GetQuery ( )
129
- {
130
- const int REGDB_E_CLASSNOTREG = unchecked ( ( int ) 0x80040154 ) ;
131
-
132
- try
133
- {
134
- // Try to CoCreate the class object.
135
- return new SetupConfiguration ( ) ;
136
- }
137
-
138
- catch ( COMException ex ) when ( ex . ErrorCode == REGDB_E_CLASSNOTREG )
139
- {
140
- // Try to get the class object using app-local call.
141
- ISetupConfiguration query ;
142
- var result = GetSetupConfiguration ( out query , IntPtr . Zero ) ;
143
-
144
- if ( result < 0 )
145
- throw new COMException ( $ "Failed to get { nameof ( query ) } ", result ) ;
146
-
147
- return query ;
148
- }
149
- }
150
-
151
- [ DllImport ( "Microsoft.VisualStudio.Setup.Configuration.Native.dll" , ExactSpelling = true , PreserveSig = true ) ]
152
- private static extern int GetSetupConfiguration (
153
- [ MarshalAs ( UnmanagedType . Interface ) ] [ Out ] out ISetupConfiguration configuration ,
154
- IntPtr reserved ) ;
155
95
}
0 commit comments