Skip to content

Commit

Permalink
Add COM workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
joeloff committed Nov 19, 2024
1 parent 6adf982 commit 7fb5f08
Showing 1 changed file with 34 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ namespace Microsoft.DotNet.Workloads.Workload
#endif
internal static class VisualStudioWorkloads
{
private static readonly object s_guard = new();

private const int REGDB_E_CLASSNOTREG = unchecked((int)0x80040154);

/// <summary>
Expand Down Expand Up @@ -158,44 +160,50 @@ internal static void WriteSDKInstallRecordsForVSWorkloads(IInstaller workloadIns
/// <returns>A list of Visual Studio instances.</returns>
private static List<ISetupInstance> GetVisualStudioInstances()
{
List<ISetupInstance> vsInstances = new();

try
// The underlying COM API has a bug where-by it's not safe for concurrent calls. Until their
// bug fix is rolled out use a lock to ensure we don't concurrently access this API.
// https://dev.azure.com/devdiv/DevDiv/_workitems/edit/2241752/
lock (s_guard)
{
SetupConfiguration setupConfiguration = new();
ISetupConfiguration2 setupConfiguration2 = setupConfiguration;
IEnumSetupInstances setupInstances = setupConfiguration2.EnumInstances();
ISetupInstance[] instances = new ISetupInstance[1];
int fetched = 0;
List<ISetupInstance> vsInstances = new();

do
try
{
setupInstances.Next(1, instances, out fetched);
SetupConfiguration setupConfiguration = new();
ISetupConfiguration2 setupConfiguration2 = setupConfiguration;
IEnumSetupInstances setupInstances = setupConfiguration2.EnumInstances();
ISetupInstance[] instances = new ISetupInstance[1];
int fetched = 0;

if (fetched > 0)
do
{
ISetupInstance2 instance = (ISetupInstance2)instances[0];
setupInstances.Next(1, instances, out fetched);

// .NET Workloads only shipped in 17.0 and later and we should only look at IDE based SKUs
// such as community, professional, and enterprise.
if (Version.TryParse(instance.GetInstallationVersion(), out Version version) &&
version.Major >= 17 &&
s_visualStudioProducts.Contains(instance.GetProduct().GetId()))
if (fetched > 0)
{
vsInstances.Add(instances[0]);
ISetupInstance2 instance = (ISetupInstance2)instances[0];

// .NET Workloads only shipped in 17.0 and later and we should only look at IDE based SKUs
// such as community, professional, and enterprise.
if (Version.TryParse(instance.GetInstallationVersion(), out Version version) &&
version.Major >= 17 &&
s_visualStudioProducts.Contains(instance.GetProduct().GetId()))
{
vsInstances.Add(instances[0]);
}
}
}
while (fetched > 0);

}
catch (COMException e) when (e.ErrorCode == REGDB_E_CLASSNOTREG)
{
// Query API not registered, good indication there are no VS installations of 15.0 or later.
// Other exceptions are passed through since that likely points to a real error.
}
while (fetched > 0);

return vsInstances;
}
catch (COMException e) when (e.ErrorCode == REGDB_E_CLASSNOTREG)
{
// Query API not registered, good indication there are no VS installations of 15.0 or later.
// Other exceptions are passed through since that likely points to a real error.
}

return vsInstances;
}
}
}

0 comments on commit 7fb5f08

Please sign in to comment.