From 404549aae0585d57432873bccc842bcac85ebc54 Mon Sep 17 00:00:00 2001
From: AR-May <67507805+AR-May@users.noreply.github.com>
Date: Fri, 20 Feb 2026 19:34:40 +0100
Subject: [PATCH 1/2] Enlighten GetFrameworkPath and GetFrameworkSdkPath
---
src/Tasks/GetFrameworkPath.cs | 1 +
src/Tasks/GetFrameworkSDKPath.cs | 371 +++++++++++++++++++------------
2 files changed, 228 insertions(+), 144 deletions(-)
diff --git a/src/Tasks/GetFrameworkPath.cs b/src/Tasks/GetFrameworkPath.cs
index 93ac97f1f62..135319a5221 100644
--- a/src/Tasks/GetFrameworkPath.cs
+++ b/src/Tasks/GetFrameworkPath.cs
@@ -12,6 +12,7 @@ namespace Microsoft.Build.Tasks
///
/// Returns the paths to the various frameworks versions.
///
+ [MSBuildMultiThreadableTask]
public class GetFrameworkPath : TaskExtension
{
#region ITask Members
diff --git a/src/Tasks/GetFrameworkSDKPath.cs b/src/Tasks/GetFrameworkSDKPath.cs
index 05f35b77b96..684ca4acfe1 100644
--- a/src/Tasks/GetFrameworkSDKPath.cs
+++ b/src/Tasks/GetFrameworkSDKPath.cs
@@ -18,18 +18,20 @@ namespace Microsoft.Build.Tasks
///
/// Returns paths to the frameworks SDK.
///
+ [MSBuildMultiThreadableTask]
public class GetFrameworkSdkPath : TaskExtension, IGetFrameworkSdkPathTaskContract
{
#region Properties
- private static string s_path;
- private static string s_version20Path;
- private static string s_version35Path;
- private static string s_version40Path;
- private static string s_version45Path;
- private static string s_version451Path;
- private static string s_version46Path;
- private static string s_version461Path;
+ private static volatile string s_path;
+ private static volatile string s_version20Path;
+ private static volatile string s_version35Path;
+ private static volatile string s_version40Path;
+ private static volatile string s_version45Path;
+ private static volatile string s_version451Path;
+ private static volatile string s_version46Path;
+ private static volatile string s_version461Path;
+ private static readonly LockType s_lockObject = new ();
///
/// The path to the latest .NET SDK if it could be found. It will be String.Empty if the SDK was not found.
@@ -39,28 +41,38 @@ public string Path
{
get
{
- if (s_path == null)
+ string path = s_path;
+ if (path == null)
{
- s_path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Latest, VisualStudioVersion.VersionLatest);
-
- if (String.IsNullOrEmpty(s_path))
- {
- Log.LogMessageFromResources(
- MessageImportance.High,
- "GetFrameworkSdkPath.CouldNotFindSDK",
- ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Latest, VisualStudioVersion.VersionLatest),
- ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Latest, VisualStudioVersion.VersionLatest));
-
- s_path = String.Empty;
- }
- else
+ lock (s_lockObject)
{
- s_path = FrameworkFileUtilities.EnsureTrailingSlash(s_path);
- Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", s_path);
+ path = s_path;
+ if (path == null)
+ {
+ path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Latest, VisualStudioVersion.VersionLatest);
+
+ if (String.IsNullOrEmpty(path))
+ {
+ Log.LogMessageFromResources(
+ MessageImportance.High,
+ "GetFrameworkSdkPath.CouldNotFindSDK",
+ ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Latest, VisualStudioVersion.VersionLatest),
+ ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Latest, VisualStudioVersion.VersionLatest));
+
+ path = String.Empty;
+ }
+ else
+ {
+ path = FrameworkFileUtilities.EnsureTrailingSlash(path);
+ Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", path);
+ }
+
+ s_path = path;
+ }
}
}
- return s_path;
+ return path;
}
set
{
@@ -76,28 +88,38 @@ public string FrameworkSdkVersion20Path
{
get
{
- if (s_version20Path == null)
+ string path = s_version20Path;
+ if (path == null)
{
- s_version20Path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version20);
-
- if (String.IsNullOrEmpty(s_version20Path))
- {
- Log.LogMessageFromResources(
- MessageImportance.High,
- "GetFrameworkSdkPath.CouldNotFindSDK",
- ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version20),
- ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version20));
-
- s_version20Path = String.Empty;
- }
- else
+ lock (s_lockObject)
{
- s_version20Path = FrameworkFileUtilities.EnsureTrailingSlash(s_version20Path);
- Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", s_version20Path);
+ path = s_version20Path;
+ if (path == null)
+ {
+ path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version20);
+
+ if (String.IsNullOrEmpty(path))
+ {
+ Log.LogMessageFromResources(
+ MessageImportance.High,
+ "GetFrameworkSdkPath.CouldNotFindSDK",
+ ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version20),
+ ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version20));
+
+ path = String.Empty;
+ }
+ else
+ {
+ path = FrameworkFileUtilities.EnsureTrailingSlash(path);
+ Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", path);
+ }
+
+ s_version20Path = path;
+ }
}
}
- return s_version20Path;
+ return path;
}
}
@@ -109,28 +131,38 @@ public string FrameworkSdkVersion35Path
{
get
{
- if (s_version35Path == null)
+ string path = s_version35Path;
+ if (path == null)
{
- s_version35Path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version35, VisualStudioVersion.VersionLatest);
-
- if (String.IsNullOrEmpty(s_version35Path))
- {
- Log.LogMessageFromResources(
- MessageImportance.High,
- "GetFrameworkSdkPath.CouldNotFindSDK",
- ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version35, VisualStudioVersion.VersionLatest),
- ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version35, VisualStudioVersion.VersionLatest));
-
- s_version35Path = String.Empty;
- }
- else
+ lock (s_lockObject)
{
- s_version35Path = FrameworkFileUtilities.EnsureTrailingSlash(s_version35Path);
- Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", s_version35Path);
+ path = s_version35Path;
+ if (path == null)
+ {
+ path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version35, VisualStudioVersion.VersionLatest);
+
+ if (String.IsNullOrEmpty(path))
+ {
+ Log.LogMessageFromResources(
+ MessageImportance.High,
+ "GetFrameworkSdkPath.CouldNotFindSDK",
+ ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version35, VisualStudioVersion.VersionLatest),
+ ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version35, VisualStudioVersion.VersionLatest));
+
+ path = String.Empty;
+ }
+ else
+ {
+ path = FrameworkFileUtilities.EnsureTrailingSlash(path);
+ Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", path);
+ }
+
+ s_version35Path = path;
+ }
}
}
- return s_version35Path;
+ return path;
}
}
@@ -142,28 +174,38 @@ public string FrameworkSdkVersion40Path
{
get
{
- if (s_version40Path == null)
+ string path = s_version40Path;
+ if (path == null)
{
- s_version40Path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version40, VisualStudioVersion.VersionLatest);
-
- if (String.IsNullOrEmpty(s_version40Path))
- {
- Log.LogMessageFromResources(
- MessageImportance.High,
- "GetFrameworkSdkPath.CouldNotFindSDK",
- ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version40, VisualStudioVersion.VersionLatest),
- ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version40, VisualStudioVersion.VersionLatest));
-
- s_version40Path = String.Empty;
- }
- else
+ lock (s_lockObject)
{
- s_version40Path = FrameworkFileUtilities.EnsureTrailingSlash(s_version40Path);
- Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", s_version40Path);
+ path = s_version40Path;
+ if (path == null)
+ {
+ path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version40, VisualStudioVersion.VersionLatest);
+
+ if (String.IsNullOrEmpty(path))
+ {
+ Log.LogMessageFromResources(
+ MessageImportance.High,
+ "GetFrameworkSdkPath.CouldNotFindSDK",
+ ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version40, VisualStudioVersion.VersionLatest),
+ ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version40, VisualStudioVersion.VersionLatest));
+
+ path = String.Empty;
+ }
+ else
+ {
+ path = FrameworkFileUtilities.EnsureTrailingSlash(path);
+ Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", path);
+ }
+
+ s_version40Path = path;
+ }
}
}
- return s_version40Path;
+ return path;
}
}
@@ -175,28 +217,38 @@ public string FrameworkSdkVersion45Path
{
get
{
- if (s_version45Path == null)
+ string path = s_version45Path;
+ if (path == null)
{
- s_version45Path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version45, VisualStudioVersion.VersionLatest);
-
- if (String.IsNullOrEmpty(s_version45Path))
- {
- Log.LogMessageFromResources(
- MessageImportance.High,
- "GetFrameworkSdkPath.CouldNotFindSDK",
- ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version45, VisualStudioVersion.VersionLatest),
- ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version45, VisualStudioVersion.VersionLatest));
-
- s_version45Path = String.Empty;
- }
- else
+ lock (s_lockObject)
{
- s_version45Path = FrameworkFileUtilities.EnsureTrailingSlash(s_version45Path);
- Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", s_version45Path);
+ path = s_version45Path;
+ if (path == null)
+ {
+ path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version45, VisualStudioVersion.VersionLatest);
+
+ if (String.IsNullOrEmpty(path))
+ {
+ Log.LogMessageFromResources(
+ MessageImportance.High,
+ "GetFrameworkSdkPath.CouldNotFindSDK",
+ ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version45, VisualStudioVersion.VersionLatest),
+ ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version45, VisualStudioVersion.VersionLatest));
+
+ path = String.Empty;
+ }
+ else
+ {
+ path = FrameworkFileUtilities.EnsureTrailingSlash(path);
+ Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", path);
+ }
+
+ s_version45Path = path;
+ }
}
}
- return s_version45Path;
+ return path;
}
}
@@ -208,28 +260,38 @@ public string FrameworkSdkVersion451Path
{
get
{
- if (s_version451Path == null)
+ string path = s_version451Path;
+ if (path == null)
{
- s_version451Path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version451, VisualStudioVersion.VersionLatest);
-
- if (String.IsNullOrEmpty(s_version451Path))
- {
- Log.LogMessageFromResources(
- MessageImportance.High,
- "GetFrameworkSdkPath.CouldNotFindSDK",
- ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version451, VisualStudioVersion.VersionLatest),
- ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version451, VisualStudioVersion.VersionLatest));
-
- s_version451Path = String.Empty;
- }
- else
+ lock (s_lockObject)
{
- s_version451Path = FrameworkFileUtilities.EnsureTrailingSlash(s_version451Path);
- Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", s_version451Path);
+ path = s_version451Path;
+ if (path == null)
+ {
+ path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version451, VisualStudioVersion.VersionLatest);
+
+ if (String.IsNullOrEmpty(path))
+ {
+ Log.LogMessageFromResources(
+ MessageImportance.High,
+ "GetFrameworkSdkPath.CouldNotFindSDK",
+ ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version451, VisualStudioVersion.VersionLatest),
+ ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version451, VisualStudioVersion.VersionLatest));
+
+ path = String.Empty;
+ }
+ else
+ {
+ path = FrameworkFileUtilities.EnsureTrailingSlash(path);
+ Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", path);
+ }
+
+ s_version451Path = path;
+ }
}
}
- return s_version451Path;
+ return path;
}
}
@@ -241,28 +303,38 @@ public string FrameworkSdkVersion46Path
{
get
{
- if (s_version46Path == null)
+ string path = s_version46Path;
+ if (path == null)
{
- s_version46Path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version46, VisualStudioVersion.VersionLatest);
-
- if (String.IsNullOrEmpty(s_version46Path))
- {
- Log.LogMessageFromResources(
- MessageImportance.High,
- "GetFrameworkSdkPath.CouldNotFindSDK",
- ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version46, VisualStudioVersion.VersionLatest),
- ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version46, VisualStudioVersion.VersionLatest));
-
- s_version46Path = String.Empty;
- }
- else
+ lock (s_lockObject)
{
- s_version46Path = FrameworkFileUtilities.EnsureTrailingSlash(s_version46Path);
- Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", s_version46Path);
+ path = s_version46Path;
+ if (path == null)
+ {
+ path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version46, VisualStudioVersion.VersionLatest);
+
+ if (String.IsNullOrEmpty(path))
+ {
+ Log.LogMessageFromResources(
+ MessageImportance.High,
+ "GetFrameworkSdkPath.CouldNotFindSDK",
+ ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version46, VisualStudioVersion.VersionLatest),
+ ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version46, VisualStudioVersion.VersionLatest));
+
+ path = String.Empty;
+ }
+ else
+ {
+ path = FrameworkFileUtilities.EnsureTrailingSlash(path);
+ Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", path);
+ }
+
+ s_version46Path = path;
+ }
}
}
- return s_version46Path;
+ return path;
}
}
@@ -274,28 +346,38 @@ public string FrameworkSdkVersion461Path
{
get
{
- if (s_version461Path == null)
+ string path = s_version461Path;
+ if (path == null)
{
- s_version461Path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version461, VisualStudioVersion.VersionLatest);
-
- if (String.IsNullOrEmpty(s_version461Path))
- {
- Log.LogMessageFromResources(
- MessageImportance.High,
- "GetFrameworkSdkPath.CouldNotFindSDK",
- ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version461, VisualStudioVersion.VersionLatest),
- ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version461, VisualStudioVersion.VersionLatest));
-
- s_version461Path = String.Empty;
- }
- else
+ lock (s_lockObject)
{
- s_version461Path = FrameworkFileUtilities.EnsureTrailingSlash(s_version461Path);
- Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", s_version461Path);
+ path = s_version461Path;
+ if (path == null)
+ {
+ path = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version461, VisualStudioVersion.VersionLatest);
+
+ if (String.IsNullOrEmpty(path))
+ {
+ Log.LogMessageFromResources(
+ MessageImportance.High,
+ "GetFrameworkSdkPath.CouldNotFindSDK",
+ ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version461, VisualStudioVersion.VersionLatest),
+ ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version461, VisualStudioVersion.VersionLatest));
+
+ path = String.Empty;
+ }
+ else
+ {
+ path = FrameworkFileUtilities.EnsureTrailingSlash(path);
+ Log.LogMessageFromResources(MessageImportance.Low, "GetFrameworkSdkPath.FoundSDK", path);
+ }
+
+ s_version461Path = path;
+ }
}
}
- return s_version461Path;
+ return path;
}
}
@@ -318,6 +400,7 @@ public override bool Execute()
}
#else
+ [MSBuildMultiThreadableTask]
public sealed class GetFrameworkSdkPath : TaskRequiresFramework, IGetFrameworkSdkPathTaskContract
{
public GetFrameworkSdkPath()
From ca6a4d6b4c99eec3619eb0c47fdfa3ed97f46d0d Mon Sep 17 00:00:00 2001
From: AR-May <67507805+AR-May@users.noreply.github.com>
Date: Mon, 23 Feb 2026 12:25:42 +0100
Subject: [PATCH 2/2] Update src/Tasks/GetFrameworkSDKPath.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
src/Tasks/GetFrameworkSDKPath.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Tasks/GetFrameworkSDKPath.cs b/src/Tasks/GetFrameworkSDKPath.cs
index 684ca4acfe1..0161001d0e8 100644
--- a/src/Tasks/GetFrameworkSDKPath.cs
+++ b/src/Tasks/GetFrameworkSDKPath.cs
@@ -31,7 +31,7 @@ public class GetFrameworkSdkPath : TaskExtension, IGetFrameworkSdkPathTaskContra
private static volatile string s_version451Path;
private static volatile string s_version46Path;
private static volatile string s_version461Path;
- private static readonly LockType s_lockObject = new ();
+ private static readonly LockType s_lockObject = new();
///
/// The path to the latest .NET SDK if it could be found. It will be String.Empty if the SDK was not found.