@@ -20,6 +20,8 @@ namespace Microsoft.DotNet.Workloads.Workload
20
20
#endif
21
21
internal static class VisualStudioWorkloads
22
22
{
23
+ private static readonly object s_guard = new ( ) ;
24
+
23
25
private const int REGDB_E_CLASSNOTREG = unchecked ( ( int ) 0x80040154 ) ;
24
26
25
27
/// <summary>
@@ -158,44 +160,50 @@ internal static void WriteSDKInstallRecordsForVSWorkloads(IInstaller workloadIns
158
160
/// <returns>A list of Visual Studio instances.</returns>
159
161
private static List < ISetupInstance > GetVisualStudioInstances ( )
160
162
{
161
- List < ISetupInstance > vsInstances = new ( ) ;
162
-
163
- try
163
+ // The underlying COM API has a bug where-by it's not safe for concurrent calls. Until their
164
+ // bug fix is rolled out use a lock to ensure we don't concurrently access this API.
165
+ // https://dev.azure.com/devdiv/DevDiv/_workitems/edit/2241752/
166
+ lock ( s_guard )
164
167
{
165
- SetupConfiguration setupConfiguration = new ( ) ;
166
- ISetupConfiguration2 setupConfiguration2 = setupConfiguration ;
167
- IEnumSetupInstances setupInstances = setupConfiguration2 . EnumInstances ( ) ;
168
- ISetupInstance [ ] instances = new ISetupInstance [ 1 ] ;
169
- int fetched = 0 ;
168
+ List < ISetupInstance > vsInstances = new ( ) ;
170
169
171
- do
170
+ try
172
171
{
173
- setupInstances . Next ( 1 , instances , out fetched ) ;
172
+ SetupConfiguration setupConfiguration = new ( ) ;
173
+ ISetupConfiguration2 setupConfiguration2 = setupConfiguration ;
174
+ IEnumSetupInstances setupInstances = setupConfiguration2 . EnumInstances ( ) ;
175
+ ISetupInstance [ ] instances = new ISetupInstance [ 1 ] ;
176
+ int fetched = 0 ;
174
177
175
- if ( fetched > 0 )
178
+ do
176
179
{
177
- ISetupInstance2 instance = ( ISetupInstance2 ) instances [ 0 ] ;
180
+ setupInstances . Next ( 1 , instances , out fetched ) ;
178
181
179
- // .NET Workloads only shipped in 17.0 and later and we should only look at IDE based SKUs
180
- // such as community, professional, and enterprise.
181
- if ( Version . TryParse ( instance . GetInstallationVersion ( ) , out Version version ) &&
182
- version . Major >= 17 &&
183
- s_visualStudioProducts . Contains ( instance . GetProduct ( ) . GetId ( ) ) )
182
+ if ( fetched > 0 )
184
183
{
185
- vsInstances . Add ( instances [ 0 ] ) ;
184
+ ISetupInstance2 instance = ( ISetupInstance2 ) instances [ 0 ] ;
185
+
186
+ // .NET Workloads only shipped in 17.0 and later and we should only look at IDE based SKUs
187
+ // such as community, professional, and enterprise.
188
+ if ( Version . TryParse ( instance . GetInstallationVersion ( ) , out Version version ) &&
189
+ version . Major >= 17 &&
190
+ s_visualStudioProducts . Contains ( instance . GetProduct ( ) . GetId ( ) ) )
191
+ {
192
+ vsInstances . Add ( instances [ 0 ] ) ;
193
+ }
186
194
}
187
195
}
196
+ while ( fetched > 0 ) ;
197
+
198
+ }
199
+ catch ( COMException e ) when ( e . ErrorCode == REGDB_E_CLASSNOTREG )
200
+ {
201
+ // Query API not registered, good indication there are no VS installations of 15.0 or later.
202
+ // Other exceptions are passed through since that likely points to a real error.
188
203
}
189
- while ( fetched > 0 ) ;
190
204
205
+ return vsInstances ;
191
206
}
192
- catch ( COMException e ) when ( e . ErrorCode == REGDB_E_CLASSNOTREG )
193
- {
194
- // Query API not registered, good indication there are no VS installations of 15.0 or later.
195
- // Other exceptions are passed through since that likely points to a real error.
196
- }
197
-
198
- return vsInstances ;
199
207
}
200
208
}
201
209
}
0 commit comments