@@ -17,6 +17,8 @@ namespace Microsoft.DotNet.Workloads.Workload
17
17
#endif
18
18
internal static class VisualStudioWorkloads
19
19
{
20
+ private static readonly object s_guard = new ( ) ;
21
+
20
22
private const int REGDB_E_CLASSNOTREG = unchecked ( ( int ) 0x80040154 ) ;
21
23
22
24
/// <summary>
@@ -125,44 +127,50 @@ internal static void GetInstalledWorkloads(IWorkloadResolver workloadResolver,
125
127
/// <returns>A list of Visual Studio instances.</returns>
126
128
private static List < ISetupInstance > GetVisualStudioInstances ( )
127
129
{
128
- List < ISetupInstance > vsInstances = new ( ) ;
129
-
130
- try
130
+ // The underlying COM API has a bug where-by it's not safe for concurrent calls. Until their
131
+ // bug fix is rolled out use a lock to ensure we don't concurrently access this API.
132
+ // https://dev.azure.com/devdiv/DevDiv/_workitems/edit/2241752/
133
+ lock ( s_guard )
131
134
{
132
- SetupConfiguration setupConfiguration = new ( ) ;
133
- ISetupConfiguration2 setupConfiguration2 = setupConfiguration ;
134
- IEnumSetupInstances setupInstances = setupConfiguration2 . EnumInstances ( ) ;
135
- ISetupInstance [ ] instances = new ISetupInstance [ 1 ] ;
136
- int fetched = 0 ;
135
+ List < ISetupInstance > vsInstances = new ( ) ;
137
136
138
- do
137
+ try
139
138
{
140
- setupInstances . Next ( 1 , instances , out fetched ) ;
139
+ SetupConfiguration setupConfiguration = new ( ) ;
140
+ ISetupConfiguration2 setupConfiguration2 = setupConfiguration ;
141
+ IEnumSetupInstances setupInstances = setupConfiguration2 . EnumInstances ( ) ;
142
+ ISetupInstance [ ] instances = new ISetupInstance [ 1 ] ;
143
+ int fetched = 0 ;
141
144
142
- if ( fetched > 0 )
145
+ do
143
146
{
144
- ISetupInstance2 instance = ( ISetupInstance2 ) instances [ 0 ] ;
147
+ setupInstances . Next ( 1 , instances , out fetched ) ;
145
148
146
- // .NET Workloads only shipped in 17.0 and later and we should only look at IDE based SKUs
147
- // such as community, professional, and enterprise.
148
- if ( Version . TryParse ( instance . GetInstallationVersion ( ) , out Version version ) &&
149
- version . Major >= 17 &&
150
- s_visualStudioProducts . Contains ( instance . GetProduct ( ) . GetId ( ) ) )
149
+ if ( fetched > 0 )
151
150
{
152
- vsInstances . Add ( instances [ 0 ] ) ;
151
+ ISetupInstance2 instance = ( ISetupInstance2 ) instances [ 0 ] ;
152
+
153
+ // .NET Workloads only shipped in 17.0 and later and we should only look at IDE based SKUs
154
+ // such as community, professional, and enterprise.
155
+ if ( Version . TryParse ( instance . GetInstallationVersion ( ) , out Version version ) &&
156
+ version . Major >= 17 &&
157
+ s_visualStudioProducts . Contains ( instance . GetProduct ( ) . GetId ( ) ) )
158
+ {
159
+ vsInstances . Add ( instances [ 0 ] ) ;
160
+ }
153
161
}
154
162
}
163
+ while ( fetched > 0 ) ;
164
+
165
+ }
166
+ catch ( COMException e ) when ( e . ErrorCode == REGDB_E_CLASSNOTREG )
167
+ {
168
+ // Query API not registered, good indication there are no VS installations of 15.0 or later.
169
+ // Other exceptions are passed through since that likely points to a real error.
155
170
}
156
- while ( fetched > 0 ) ;
157
171
172
+ return vsInstances ;
158
173
}
159
- catch ( COMException e ) when ( e . ErrorCode == REGDB_E_CLASSNOTREG )
160
- {
161
- // Query API not registered, good indication there are no VS installations of 15.0 or later.
162
- // Other exceptions are passed through since that likely points to a real error.
163
- }
164
-
165
- return vsInstances ;
166
174
}
167
175
}
168
176
}
0 commit comments