diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHandler.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHandler.cs
index 4255641119..a2ce548535 100644
--- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHandler.cs
+++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHandler.cs
@@ -5,9 +5,6 @@
using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.AppContainer;
#endif
using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface;
-#if NETFRAMEWORK
-using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;
-#endif
namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices;
@@ -79,7 +76,7 @@ public bool IsAssemblyReferenced(AssemblyName assemblyName, string source)
{
#if NETFRAMEWORK
// This loads the dll in a different app domain. We can optimize this to load in the current domain since this code could be run in a new app domain anyway.
- bool? utfReference = AssemblyHelper.DoesReferencesAssembly(source, assemblyName);
+ bool? utfReference = DoesSourceReferenceAssembly(source, assemblyName);
// If no reference to UTF don't run discovery. Take conservative approach. If not able to find proceed with discovery.
return !utfReference.HasValue || utfReference.Value;
@@ -94,6 +91,73 @@ public bool IsAssemblyReferenced(AssemblyName assemblyName, string source)
#endif
}
+#if NETFRAMEWORK
+ ///
+ /// Checks whether the source assembly directly references the given assembly.
+ /// Only the assembly simple name and public key token are matched; version is ignored.
+ /// Returns if the reference could not be determined.
+ ///
+ /// The path to the source assembly to inspect.
+ /// The assembly to look for in the source's references.
+ /// if referenced, if not, if undeterminable.
+ private static bool? DoesSourceReferenceAssembly(string source, AssemblyName referenceAssembly)
+ {
+ if (string.IsNullOrEmpty(source) || referenceAssembly is null)
+ {
+ return null;
+ }
+
+ try
+ {
+ string? referenceAssemblyName = referenceAssembly.Name;
+ byte[] referenceAssemblyPublicKeyToken = referenceAssembly.GetPublicKeyToken();
+
+ // ReflectionOnlyLoadFrom loads from the specified path only (no probing) and does not
+ // execute any code from the loaded assembly.
+ var assembly = Assembly.ReflectionOnlyLoadFrom(source);
+
+ foreach (AssemblyName referencedAssembly in assembly.GetReferencedAssemblies())
+ {
+ // Match without version: only the simple name and public key token.
+ if (!string.Equals(referencedAssembly.Name, referenceAssemblyName, StringComparison.OrdinalIgnoreCase))
+ {
+ continue;
+ }
+
+ if (ArePublicKeyTokensEqual(referencedAssembly.GetPublicKeyToken(), referenceAssemblyPublicKeyToken))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ catch
+ {
+ // Return null if we are not able to check.
+ return null;
+ }
+ }
+
+ private static bool ArePublicKeyTokensEqual(byte[] left, byte[] right)
+ {
+ if (left.Length != right.Length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < left.Length; ++i)
+ {
+ if (left[i] != right[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+#endif
+
///
/// Gets the set of sources (dll's/exe's) that contain tests. If a source is a package (appx), return the file (dll/exe) that contains tests from it.
///