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