diff --git a/SampleTestAssembly/SampleTestAssembly.csproj b/SampleTestAssembly/SampleTestAssembly.csproj
index b8b1d3e..497d7de 100644
--- a/SampleTestAssembly/SampleTestAssembly.csproj
+++ b/SampleTestAssembly/SampleTestAssembly.csproj
@@ -1,7 +1,7 @@
- net461
+ netstandard2.0
diff --git a/xunit.runner.data/xunit.runner.data.csproj b/xunit.runner.data/xunit.runner.data.csproj
index d22e7a7..d69f99b 100644
--- a/xunit.runner.data/xunit.runner.data.csproj
+++ b/xunit.runner.data/xunit.runner.data.csproj
@@ -2,7 +2,7 @@
Xunit.Runner.Data
- net452
+ netstandard2.0
\ No newline at end of file
diff --git a/xunit.runner.worker/AssemblyHelper.cs b/xunit.runner.worker/AssemblyHelper.cs
new file mode 100644
index 0000000..d8283c4
--- /dev/null
+++ b/xunit.runner.worker/AssemblyHelper.cs
@@ -0,0 +1,110 @@
+#if NETFRAMEWORK
+
+// Taken from https://github.com/xunit/xunit/blob/master/src/common/AssemblyResolution/AssemblyHelper_Desktop.cs
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Reflection;
+using Xunit.Abstractions;
+using Xunit.Sdk;
+
+namespace Xunit
+{
+ ///
+ /// This class provides assistance with assembly resolution for missing assemblies.
+ ///
+ class AssemblyHelper : LongLivedMarshalByRefObject, IDisposable
+ {
+ static readonly string[] Extensions = { ".dll", ".exe" };
+
+ readonly string directory;
+ readonly IMessageSink internalDiagnosticsMessageSink;
+ readonly Dictionary lookupCache = new Dictionary();
+
+ ///
+ /// Constructs an instance using the given for resolution.
+ ///
+ /// The directory to use for resolving assemblies.
+ public AssemblyHelper(string directory) : this(directory, null) { }
+
+ ///
+ /// Constructs an instance using the given for resolution.
+ ///
+ /// The directory to use for resolving assemblies.
+ /// The message sink to send internal diagnostics messages to
+ public AssemblyHelper(string directory, IMessageSink internalDiagnosticsMessageSink)
+ {
+ this.directory = directory;
+ this.internalDiagnosticsMessageSink = internalDiagnosticsMessageSink;
+
+ AppDomain.CurrentDomain.AssemblyResolve += Resolve;
+ }
+
+ ///
+ public void Dispose()
+ => AppDomain.CurrentDomain.AssemblyResolve -= Resolve;
+
+ Assembly LoadAssembly(AssemblyName assemblyName)
+ {
+ if (lookupCache.TryGetValue(assemblyName.Name, out var result))
+ return result;
+
+ var path = Path.Combine(directory, assemblyName.Name);
+ result = ResolveAndLoadAssembly(path, out var resolvedAssemblyPath);
+
+ if (internalDiagnosticsMessageSink != null)
+ {
+ if (result == null)
+ internalDiagnosticsMessageSink.OnMessage(new DiagnosticMessage($"[AssemblyHelper_Desktop.LoadAssembly] Resolution for '{assemblyName.Name}' failed, passed down to next resolver"));
+ else
+ internalDiagnosticsMessageSink.OnMessage(new DiagnosticMessage($"[AssemblyHelper_Desktop.LoadAssembly] Resolved '{assemblyName.Name}' to '{resolvedAssemblyPath}'"));
+ }
+
+ lookupCache[assemblyName.Name] = result;
+ return result;
+ }
+
+ Assembly Resolve(object sender, ResolveEventArgs args)
+ => LoadAssembly(new AssemblyName(args.Name));
+
+ Assembly ResolveAndLoadAssembly(string pathWithoutExtension, out string resolvedAssemblyPath)
+ {
+ foreach (var extension in Extensions)
+ {
+ resolvedAssemblyPath = pathWithoutExtension + extension;
+
+ try
+ {
+ if (File.Exists(resolvedAssemblyPath))
+ return Assembly.LoadFrom(resolvedAssemblyPath);
+ }
+ catch { }
+ }
+
+ resolvedAssemblyPath = null;
+ return null;
+ }
+
+ ///
+ /// Subscribes to the appropriate assembly resolution event, to provide automatic assembly resolution for
+ /// an assembly and any of its dependencies. Depending on the target platform, this may include the use
+ /// of the .deps.json file generated during the build process.
+ ///
+ /// An object which, when disposed, un-subscribes.
+ public static IDisposable SubscribeResolveForAssembly(string assemblyFileName, IMessageSink internalDiagnosticsMessageSink = null)
+ => new AssemblyHelper(Path.GetDirectoryName(Path.GetFullPath(assemblyFileName)), internalDiagnosticsMessageSink);
+
+ ///
+ /// Subscribes to the appropriate assembly resolution event, to provide automatic assembly resolution for
+ /// an assembly and any of its dependencies. Depending on the target platform, this may include the use
+ /// of the .deps.json file generated during the build process.
+ ///
+ /// An object which, when disposed, un-subscribes.
+ public static IDisposable SubscribeResolveForAssembly(Type typeInAssembly, IMessageSink internalDiagnosticsMessageSink = null)
+ => new AssemblyHelper(Path.GetDirectoryName(typeInAssembly.Assembly.Location), internalDiagnosticsMessageSink);
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/xunit.runner.worker/XunitUtil.cs b/xunit.runner.worker/XunitUtil.cs
index f3e8e74..7a5f6a4 100644
--- a/xunit.runner.worker/XunitUtil.cs
+++ b/xunit.runner.worker/XunitUtil.cs
@@ -9,7 +9,7 @@ namespace Xunit.Runner.Worker
protected static void Go(string assemblyFileName, Stream stream, AppDomainSupport appDomainSupport,
Action action)
{
- using (AssemblyHelper.SubscribeResolve())
+ using (AssemblyHelper.SubscribeResolveForAssembly(assemblyFileName))
using (var xunit = new XunitFrontController(appDomainSupport, assemblyFileName, shadowCopy: false))
using (var writer = new ClientWriter(stream))
{
diff --git a/xunit.runner.worker/xunit.runner.worker.csproj b/xunit.runner.worker/xunit.runner.worker.csproj
index e1d06a2..fec894e 100644
--- a/xunit.runner.worker/xunit.runner.worker.csproj
+++ b/xunit.runner.worker/xunit.runner.worker.csproj
@@ -3,11 +3,11 @@
Exe
Xunit.Runner.Worker
- net452
+ net472
-
+
diff --git a/xunit.runner.wpf/xunit.runner.wpf.csproj b/xunit.runner.wpf/xunit.runner.wpf.csproj
index 6505610..0c94732 100644
--- a/xunit.runner.wpf/xunit.runner.wpf.csproj
+++ b/xunit.runner.wpf/xunit.runner.wpf.csproj
@@ -9,6 +9,7 @@
Pilchie
true
true
+ net472
XUnit Gui written in WPF
https://github.com/Pilchie/xunit.runner.wpf
https://github.com/Pilchie/xunit.runner.wpf
@@ -27,7 +28,6 @@
-