From ad58b6da48c4d5254eb6b2b1dc50298b32962b9f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 27 Nov 2025 09:49:56 +0000
Subject: [PATCH 01/12] Initial plan
From 612208fc961dd26b51ced14a38f11528d482d1a9 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 27 Nov 2025 09:58:42 +0000
Subject: [PATCH 02/12] Fix OSConditionAttribute to use RuntimeInformation via
reflection for .NET Framework
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
.../TestMethod/OSConditionAttribute.cs | 76 ++++++++++++++++++-
1 file changed, 73 insertions(+), 3 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index 502a3aa5e1..f7ed928700 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -50,9 +50,8 @@ public OSConditionAttribute(OperatingSystems operatingSystems)
/// Gets a value indicating whether the test method or test class should be ignored.
///
public override bool IsConditionMet
-#if NET462
- // On .NET Framework, we are sure we are running on Windows.
- => (_operatingSystems & OperatingSystems.Windows) != 0;
+#if NETFRAMEWORK
+ => IsConditionMetNetFramework();
#else
{
get
@@ -79,6 +78,77 @@ public override bool IsConditionMet
}
#endif
+#if NETFRAMEWORK
+ private bool IsConditionMetNetFramework()
+ {
+ // RuntimeInformation.IsOSPlatform is available in .NET Framework 4.7.1+.
+ // For older .NET Framework versions or environments where the API is not available,
+ // we fall back to assuming Windows.
+ // This also handles Mono which supports RuntimeInformation API and can run on non-Windows platforms.
+ Type? runtimeInformationType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
+ ?? Type.GetType("System.Runtime.InteropServices.RuntimeInformation, mscorlib");
+
+ if (runtimeInformationType is null)
+ {
+ // API not available, assume Windows
+ return (_operatingSystems & OperatingSystems.Windows) != 0;
+ }
+
+ MethodInfo? isOSPlatformMethod = runtimeInformationType.GetMethod("IsOSPlatform", BindingFlags.Public | BindingFlags.Static);
+ if (isOSPlatformMethod is null)
+ {
+ // API not available, assume Windows
+ return (_operatingSystems & OperatingSystems.Windows) != 0;
+ }
+
+ Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
+ ?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib");
+
+ if (osPlatformType is null)
+ {
+ // API not available, assume Windows
+ return (_operatingSystems & OperatingSystems.Windows) != 0;
+ }
+
+ if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "Windows"))
+ {
+ return (_operatingSystems & OperatingSystems.Windows) != 0;
+ }
+ else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "Linux"))
+ {
+ return (_operatingSystems & OperatingSystems.Linux) != 0;
+ }
+ else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "OSX"))
+ {
+ return (_operatingSystems & OperatingSystems.OSX) != 0;
+ }
+ else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "FreeBSD"))
+ {
+ return (_operatingSystems & OperatingSystems.FreeBSD) != 0;
+ }
+
+ return false;
+ }
+
+ private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, Type osPlatformType, string osName)
+ {
+ MethodInfo? createMethod = osPlatformType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static);
+ if (createMethod is null)
+ {
+ return false;
+ }
+
+ object? osPlatform = createMethod.Invoke(null, [osName]);
+ if (osPlatform is null)
+ {
+ return false;
+ }
+
+ object? result = isOSPlatformMethod.Invoke(null, [osPlatform]);
+ return result is true;
+ }
+#endif
+
///
/// Gets the group name for this attribute.
///
From 573b07c7b93e5f0b2ff8e50e291db7b4f8eef7e6 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 27 Nov 2025 10:00:18 +0000
Subject: [PATCH 03/12] Address code review feedback: use explicit object array
syntax
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
.../Attributes/TestMethod/OSConditionAttribute.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index f7ed928700..a35edbd7b7 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -138,13 +138,13 @@ private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, Typ
return false;
}
- object? osPlatform = createMethod.Invoke(null, [osName]);
+ object? osPlatform = createMethod.Invoke(null, new object[] { osName });
if (osPlatform is null)
{
return false;
}
- object? result = isOSPlatformMethod.Invoke(null, [osPlatform]);
+ object? result = isOSPlatformMethod.Invoke(null, new object[] { osPlatform });
return result is true;
}
#endif
From 9ea40f98b6f879e9cc08d91003fe49f980ca564e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 27 Nov 2025 10:03:25 +0000
Subject: [PATCH 04/12] Optimize OS detection with caching and simpler type
loading
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
.../TestMethod/OSConditionAttribute.cs | 63 +++++++++++--------
1 file changed, 36 insertions(+), 27 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index a35edbd7b7..836ceade2c 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -21,6 +21,11 @@ public sealed class OSConditionAttribute : ConditionBaseAttribute
#endif
#endif
+#if NETFRAMEWORK
+ // Cache the detected OS to avoid repeated reflection calls
+ private static readonly OperatingSystems? s_detectedOS = DetectCurrentOS();
+#endif
+
private readonly OperatingSystems _operatingSystems;
///
@@ -51,7 +56,14 @@ public OSConditionAttribute(OperatingSystems operatingSystems)
///
public override bool IsConditionMet
#if NETFRAMEWORK
- => IsConditionMetNetFramework();
+ {
+ get
+ {
+ // If we couldn't detect the OS via reflection, assume Windows
+ OperatingSystems currentOS = s_detectedOS ?? OperatingSystems.Windows;
+ return (_operatingSystems & currentOS) != 0;
+ }
+ }
#else
{
get
@@ -79,65 +91,62 @@ public override bool IsConditionMet
#endif
#if NETFRAMEWORK
- private bool IsConditionMetNetFramework()
+ private static OperatingSystems? DetectCurrentOS()
{
// RuntimeInformation.IsOSPlatform is available in .NET Framework 4.7.1+.
// For older .NET Framework versions or environments where the API is not available,
- // we fall back to assuming Windows.
+ // we return null to fall back to assuming Windows.
// This also handles Mono which supports RuntimeInformation API and can run on non-Windows platforms.
- Type? runtimeInformationType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
+ Type? runtimeInformationType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation")
?? Type.GetType("System.Runtime.InteropServices.RuntimeInformation, mscorlib");
if (runtimeInformationType is null)
{
- // API not available, assume Windows
- return (_operatingSystems & OperatingSystems.Windows) != 0;
+ return null;
}
MethodInfo? isOSPlatformMethod = runtimeInformationType.GetMethod("IsOSPlatform", BindingFlags.Public | BindingFlags.Static);
if (isOSPlatformMethod is null)
{
- // API not available, assume Windows
- return (_operatingSystems & OperatingSystems.Windows) != 0;
+ return null;
}
- Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
+ Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation")
?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib");
if (osPlatformType is null)
{
- // API not available, assume Windows
- return (_operatingSystems & OperatingSystems.Windows) != 0;
+ return null;
}
- if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "Windows"))
+ MethodInfo? createMethod = osPlatformType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static);
+ if (createMethod is null)
{
- return (_operatingSystems & OperatingSystems.Windows) != 0;
+ return null;
}
- else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "Linux"))
+
+ if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "Windows"))
+ {
+ return OperatingSystems.Windows;
+ }
+ else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "Linux"))
{
- return (_operatingSystems & OperatingSystems.Linux) != 0;
+ return OperatingSystems.Linux;
}
- else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "OSX"))
+ else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "OSX"))
{
- return (_operatingSystems & OperatingSystems.OSX) != 0;
+ return OperatingSystems.OSX;
}
- else if (IsOSPlatformViaReflection(isOSPlatformMethod, osPlatformType, "FreeBSD"))
+ else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "FreeBSD"))
{
- return (_operatingSystems & OperatingSystems.FreeBSD) != 0;
+ return OperatingSystems.FreeBSD;
}
- return false;
+ return null;
}
- private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, Type osPlatformType, string osName)
+ private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, MethodInfo createMethod, string osName)
{
- MethodInfo? createMethod = osPlatformType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static);
- if (createMethod is null)
- {
- return false;
- }
-
object? osPlatform = createMethod.Invoke(null, new object[] { osName });
if (osPlatform is null)
{
From 70f93bfb66921c132995e06c8531a064ba683410 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 27 Nov 2025 10:04:45 +0000
Subject: [PATCH 05/12] Add exception handling for reflection invocations
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
.../TestMethod/OSConditionAttribute.cs | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index 836ceade2c..817f703577 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -147,14 +147,22 @@ public override bool IsConditionMet
private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, MethodInfo createMethod, string osName)
{
- object? osPlatform = createMethod.Invoke(null, new object[] { osName });
- if (osPlatform is null)
+ try
{
+ object? osPlatform = createMethod.Invoke(null, new object[] { osName });
+ if (osPlatform is null)
+ {
+ return false;
+ }
+
+ object? result = isOSPlatformMethod.Invoke(null, new object[] { osPlatform });
+ return result is true;
+ }
+ catch
+ {
+ // Reflection invocation failed, treat as OS not matching
return false;
}
-
- object? result = isOSPlatformMethod.Invoke(null, new object[] { osPlatform });
- return result is true;
}
#endif
From 7128c0af0d34870086600e254335b138981fb50c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Amaury=20Lev=C3=A9?=
Date: Fri, 28 Nov 2025 17:55:32 +0100
Subject: [PATCH 06/12] Apply suggestions from code review
---
.../Attributes/TestMethod/OSConditionAttribute.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index 817f703577..bb546bdfb6 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -23,7 +23,7 @@ public sealed class OSConditionAttribute : ConditionBaseAttribute
#if NETFRAMEWORK
// Cache the detected OS to avoid repeated reflection calls
- private static readonly OperatingSystems? s_detectedOS = DetectCurrentOS();
+ private static readonly OperatingSystems? DetectedOS = DetectCurrentOS();
#endif
private readonly OperatingSystems _operatingSystems;
@@ -60,7 +60,7 @@ public override bool IsConditionMet
get
{
// If we couldn't detect the OS via reflection, assume Windows
- OperatingSystems currentOS = s_detectedOS ?? OperatingSystems.Windows;
+ OperatingSystems currentOS = DetectedOS ?? OperatingSystems.Windows;
return (_operatingSystems & currentOS) != 0;
}
}
From 9c642633b9095feebd95651e0840b7268fc93406 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Amaury=20Lev=C3=A9?=
Date: Sun, 30 Nov 2025 07:32:25 +0100
Subject: [PATCH 07/12] Update
src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
Co-authored-by: Youssef Victor
---
.../TestFramework/Attributes/TestMethod/OSConditionAttribute.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index bb546bdfb6..1a3f7c6f25 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -55,7 +55,7 @@ public OSConditionAttribute(OperatingSystems operatingSystems)
/// Gets a value indicating whether the test method or test class should be ignored.
///
public override bool IsConditionMet
-#if NETFRAMEWORK
+#if NET462
{
get
{
From 09af2d3f9d78b0a9ddeaa66979b8bf0bc11b3a0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Amaury=20Lev=C3=A9?=
Date: Sun, 30 Nov 2025 07:32:38 +0100
Subject: [PATCH 08/12] Update
src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
Co-authored-by: Youssef Victor
---
.../TestFramework/Attributes/TestMethod/OSConditionAttribute.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index 1a3f7c6f25..81301c2c53 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -21,7 +21,7 @@ public sealed class OSConditionAttribute : ConditionBaseAttribute
#endif
#endif
-#if NETFRAMEWORK
+#if NET462
// Cache the detected OS to avoid repeated reflection calls
private static readonly OperatingSystems? DetectedOS = DetectCurrentOS();
#endif
From 449e696569fe668955f46fd877092810123af784 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Amaury=20Lev=C3=A9?=
Date: Mon, 1 Dec 2025 10:48:25 +0100
Subject: [PATCH 09/12] Update
src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
Co-authored-by: Youssef Victor
---
.../TestFramework/Attributes/TestMethod/OSConditionAttribute.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index 81301c2c53..26d51c278e 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -90,7 +90,7 @@ public override bool IsConditionMet
}
#endif
-#if NETFRAMEWORK
+#if NET462
private static OperatingSystems? DetectCurrentOS()
{
// RuntimeInformation.IsOSPlatform is available in .NET Framework 4.7.1+.
From 7f4999d7b4b06734bc336c05925ac264097e3afb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Amaury=20Lev=C3=A9?=
Date: Mon, 1 Dec 2025 13:24:41 +0100
Subject: [PATCH 10/12] Fix code
---
.../TestMethod/OSConditionAttribute.cs | 51 +++++++------------
1 file changed, 19 insertions(+), 32 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index 26d51c278e..bd542b2e00 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -55,19 +55,14 @@ public OSConditionAttribute(OperatingSystems operatingSystems)
/// Gets a value indicating whether the test method or test class should be ignored.
///
public override bool IsConditionMet
-#if NET462
{
get
{
+#if NET462
// If we couldn't detect the OS via reflection, assume Windows
OperatingSystems currentOS = DetectedOS ?? OperatingSystems.Windows;
return (_operatingSystems & currentOS) != 0;
- }
- }
#else
- {
- get
- {
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return (_operatingSystems & OperatingSystems.Windows) != 0;
@@ -86,9 +81,9 @@ public override bool IsConditionMet
}
return false;
+#endif
}
}
-#endif
#if NET462
private static OperatingSystems? DetectCurrentOS()
@@ -99,7 +94,6 @@ public override bool IsConditionMet
// This also handles Mono which supports RuntimeInformation API and can run on non-Windows platforms.
Type? runtimeInformationType = Type.GetType("System.Runtime.InteropServices.RuntimeInformation, System.Runtime.InteropServices.RuntimeInformation")
?? Type.GetType("System.Runtime.InteropServices.RuntimeInformation, mscorlib");
-
if (runtimeInformationType is null)
{
return null;
@@ -113,31 +107,32 @@ public override bool IsConditionMet
Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation")
?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib");
-
if (osPlatformType is null)
{
return null;
}
- MethodInfo? createMethod = osPlatformType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static);
- if (createMethod is null)
- {
- return null;
- }
+ // Use the predefined static properties instead of Create() method
+ // On Mono, the static properties use uppercase strings (e.g., "LINUX") while Create() uses the provided casing,
+ // and IsOSPlatform performs case-sensitive comparison against the predefined values.
+ PropertyInfo? windowsProp = osPlatformType.GetProperty("Windows", BindingFlags.Public | BindingFlags.Static);
+ PropertyInfo? linuxProp = osPlatformType.GetProperty("Linux", BindingFlags.Public | BindingFlags.Static);
+ PropertyInfo? osxProp = osPlatformType.GetProperty("OSX", BindingFlags.Public | BindingFlags.Static);
+ PropertyInfo? freebsdProp = osPlatformType.GetProperty("FreeBSD", BindingFlags.Public | BindingFlags.Static);
- if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "Windows"))
+ if (windowsProp != null && IsOSPlatformViaProperty(isOSPlatformMethod, windowsProp))
{
return OperatingSystems.Windows;
}
- else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "Linux"))
+ else if (linuxProp != null && IsOSPlatformViaProperty(isOSPlatformMethod, linuxProp))
{
return OperatingSystems.Linux;
}
- else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "OSX"))
+ else if (osxProp != null && IsOSPlatformViaProperty(isOSPlatformMethod, osxProp))
{
return OperatingSystems.OSX;
}
- else if (IsOSPlatformViaReflection(isOSPlatformMethod, createMethod, "FreeBSD"))
+ else if (freebsdProp != null && IsOSPlatformViaProperty(isOSPlatformMethod, freebsdProp))
{
return OperatingSystems.FreeBSD;
}
@@ -145,24 +140,16 @@ public override bool IsConditionMet
return null;
}
- private static bool IsOSPlatformViaReflection(MethodInfo isOSPlatformMethod, MethodInfo createMethod, string osName)
+ private static bool IsOSPlatformViaProperty(MethodInfo isOSPlatformMethod, PropertyInfo osPlatformProperty)
{
- try
- {
- object? osPlatform = createMethod.Invoke(null, new object[] { osName });
- if (osPlatform is null)
- {
- return false;
- }
-
- object? result = isOSPlatformMethod.Invoke(null, new object[] { osPlatform });
- return result is true;
- }
- catch
+ object? osPlatform = osPlatformProperty.GetValue(null);
+ if (osPlatform is null)
{
- // Reflection invocation failed, treat as OS not matching
return false;
}
+
+ object? result = isOSPlatformMethod.Invoke(null, [osPlatform]);
+ return result is true;
}
#endif
From bf1c2cb458d19113617505b08e033b01099ddb53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Amaury=20Lev=C3=A9?=
Date: Tue, 2 Dec 2025 10:54:35 +0100
Subject: [PATCH 11/12] Update logic of detection
---
.../TestMethod/OSConditionAttribute.cs | 30 ++++++++++---------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index bd542b2e00..6f6adced68 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -55,14 +55,12 @@ public OSConditionAttribute(OperatingSystems operatingSystems)
/// Gets a value indicating whether the test method or test class should be ignored.
///
public override bool IsConditionMet
+#if NET462
+ => DetectedOS is not null && (_operatingSystems & DetectedOS) != 0;
+#else
{
get
{
-#if NET462
- // If we couldn't detect the OS via reflection, assume Windows
- OperatingSystems currentOS = DetectedOS ?? OperatingSystems.Windows;
- return (_operatingSystems & currentOS) != 0;
-#else
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return (_operatingSystems & OperatingSystems.Windows) != 0;
@@ -81,11 +79,17 @@ public override bool IsConditionMet
}
return false;
-#endif
}
}
+#endif
#if NET462
+ ///
+ /// Detects the current operating system using reflection to maintain compatibility with .NET Framework 4.6.2.
+ ///
+ ///
+ /// The detected operating system, or null if the OS could not be determined.
+ ///
private static OperatingSystems? DetectCurrentOS()
{
// RuntimeInformation.IsOSPlatform is available in .NET Framework 4.7.1+.
@@ -96,20 +100,22 @@ public override bool IsConditionMet
?? Type.GetType("System.Runtime.InteropServices.RuntimeInformation, mscorlib");
if (runtimeInformationType is null)
{
- return null;
+ return OperatingSystems.Windows;
}
MethodInfo? isOSPlatformMethod = runtimeInformationType.GetMethod("IsOSPlatform", BindingFlags.Public | BindingFlags.Static);
if (isOSPlatformMethod is null)
{
- return null;
+ // Fallback to Windows if the method is not found
+ return OperatingSystems.Windows;
}
Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation")
?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib");
if (osPlatformType is null)
{
- return null;
+ // This should not happen, as OSPlatform is required for IsOSPlatform method
+ throw ApplicationStateGuard.Unreachable();
}
// Use the predefined static properties instead of Create() method
@@ -137,17 +143,13 @@ public override bool IsConditionMet
return OperatingSystems.FreeBSD;
}
+ // Unknown OS
return null;
}
private static bool IsOSPlatformViaProperty(MethodInfo isOSPlatformMethod, PropertyInfo osPlatformProperty)
{
object? osPlatform = osPlatformProperty.GetValue(null);
- if (osPlatform is null)
- {
- return false;
- }
-
object? result = isOSPlatformMethod.Invoke(null, [osPlatform]);
return result is true;
}
From a729167f755359b7618dc76eae79a9b71d625fc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Amaury=20Lev=C3=A9?=
Date: Tue, 2 Dec 2025 11:20:34 +0100
Subject: [PATCH 12/12] Apply suggestion from @Evangelink
---
.../Attributes/TestMethod/OSConditionAttribute.cs | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
index 6f6adced68..f12ca33e45 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/OSConditionAttribute.cs
@@ -111,12 +111,8 @@ public override bool IsConditionMet
}
Type? osPlatformType = Type.GetType("System.Runtime.InteropServices.OSPlatform, System.Runtime.InteropServices.RuntimeInformation")
- ?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib");
- if (osPlatformType is null)
- {
- // This should not happen, as OSPlatform is required for IsOSPlatform method
- throw ApplicationStateGuard.Unreachable();
- }
+ ?? Type.GetType("System.Runtime.InteropServices.OSPlatform, mscorlib")
+ ?? throw ApplicationStateGuard.Unreachable();
// Use the predefined static properties instead of Create() method
// On Mono, the static properties use uppercase strings (e.g., "LINUX") while Create() uses the provided casing,