@@ -20,6 +20,8 @@ namespace Microsoft.DotNet.Workloads.Workload
2020#endif
2121 internal static class VisualStudioWorkloads
2222 {
23+ private static readonly object s_guard = new ( ) ;
24+
2325 private const int REGDB_E_CLASSNOTREG = unchecked ( ( int ) 0x80040154 ) ;
2426
2527 /// <summary>
@@ -158,44 +160,50 @@ internal static void WriteSDKInstallRecordsForVSWorkloads(IInstaller workloadIns
158160 /// <returns>A list of Visual Studio instances.</returns>
159161 private static List < ISetupInstance > GetVisualStudioInstances ( )
160162 {
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 )
164167 {
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 ( ) ;
170169
171- do
170+ try
172171 {
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 ;
174177
175- if ( fetched > 0 )
178+ do
176179 {
177- ISetupInstance2 instance = ( ISetupInstance2 ) instances [ 0 ] ;
180+ setupInstances . Next ( 1 , instances , out fetched ) ;
178181
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 )
184183 {
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+ }
186194 }
187195 }
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.
188203 }
189- while ( fetched > 0 ) ;
190204
205+ return vsInstances ;
191206 }
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 ;
199207 }
200208 }
201209}
0 commit comments