@@ -17,6 +17,8 @@ namespace Microsoft.DotNet.Workloads.Workload
1717#endif
1818    internal  static   class  VisualStudioWorkloads 
1919    { 
20+         private  static   readonly  object  s_guard  =  new ( ) ; 
21+ 
2022        private  const  int  REGDB_E_CLASSNOTREG  =  unchecked ( ( int ) 0x80040154 ) ; 
2123
2224        /// <summary> 
@@ -125,44 +127,50 @@ internal static void GetInstalledWorkloads(IWorkloadResolver workloadResolver,
125127        /// <returns>A list of Visual Studio instances.</returns> 
126128        private  static   List < ISetupInstance >  GetVisualStudioInstances ( ) 
127129        { 
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 ) 
131134            { 
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 ( ) ; 
137136
138-                 do 
137+                 try 
139138                { 
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 ; 
141144
142-                     if   ( fetched   >   0 ) 
145+                     do 
143146                    { 
144-                         ISetupInstance2   instance   =   ( ISetupInstance2 ) instances [ 0 ] ; 
147+                         setupInstances . Next ( 1 ,   instances ,   out   fetched ) ; 
145148
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 ) 
151150                        { 
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+                             } 
153161                        } 
154162                    } 
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. 
155170                } 
156-                 while  ( fetched  >  0 ) ; 
157171
172+                 return  vsInstances ; 
158173            } 
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 ; 
166174        } 
167175    } 
168176} 
0 commit comments