Skip to content

Commit af23cd6

Browse files
authored
Merge pull request #84640 from vseanreesermsft/internal-merge-7.0-2023-04-11-1033
Merging internal commits for release/7.0
2 parents a283bb9 + 4e9cde7 commit af23cd6

File tree

16 files changed

+237
-29
lines changed

16 files changed

+237
-29
lines changed

src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,8 @@ internal static unsafe void FixupModuleCell(ModuleFixupCell* pCell)
309309

310310
hModule = NativeLibrary.LoadBySearch(
311311
callingAssembly,
312-
searchAssemblyDirectory: false,
313-
dllImportSearchPathFlags: 0,
312+
searchAssemblyDirectory: (dllImportSearchPath & (uint)DllImportSearchPath.AssemblyDirectory) != 0,
313+
dllImportSearchPathFlags: (int)(dllImportSearchPath & ~(uint)DllImportSearchPath.AssemblyDirectory),
314314
ref loadLibErrorTracker,
315315
moduleName);
316316

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/NativeLibrary.NativeAot.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal static IntPtr LoadLibraryByName(string libraryName, Assembly assembly,
2020
bool searchAssemblyDirectory;
2121
if (searchPath.HasValue)
2222
{
23-
searchPathFlags = (int)(searchPath.Value & ~DllImportSearchPath.AssemblyDirectory);
23+
searchPathFlags = (int)(searchPath!.Value & ~DllImportSearchPath.AssemblyDirectory);
2424
searchAssemblyDirectory = (searchPath.Value & DllImportSearchPath.AssemblyDirectory) != 0;
2525
}
2626
else

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/PInvokeMethodFixupNode.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Reflection.Metadata;
56
using System.Runtime.InteropServices;
67

78
using Internal.IL.Stubs;
@@ -97,23 +98,35 @@ public PInvokeMethodData(PInvokeLazyFixupField pInvokeLazyFixupField)
9798
PInvokeMetadata metadata = pInvokeLazyFixupField.PInvokeMetadata;
9899
ModuleDesc declaringModule = ((MetadataType)pInvokeLazyFixupField.TargetMethod.OwningType).Module;
99100

100-
DllImportSearchPath? dllImportSearchPath = default;
101-
if (declaringModule.Assembly is EcmaAssembly asm)
101+
CustomAttributeValue<TypeDesc>? decodedAttr = null;
102+
103+
// Look for DefaultDllImportSearchPath on the method
104+
if (pInvokeLazyFixupField.TargetMethod is EcmaMethod method)
105+
{
106+
decodedAttr = method.GetDecodedCustomAttribute("System.Runtime.InteropServices", "DefaultDllImportSearchPathsAttribute");
107+
}
108+
109+
// If the attribute it wasn't found on the method, look for it on the assembly
110+
if (!decodedAttr.HasValue && declaringModule.Assembly is EcmaAssembly asm)
102111
{
103112
// We look for [assembly:DefaultDllImportSearchPaths(...)]
104113
var attrHandle = asm.MetadataReader.GetCustomAttributeHandle(asm.AssemblyDefinition.GetCustomAttributes(),
105114
"System.Runtime.InteropServices", "DefaultDllImportSearchPathsAttribute");
106115
if (!attrHandle.IsNil)
107116
{
108117
var attr = asm.MetadataReader.GetCustomAttribute(attrHandle);
109-
var decoded = attr.DecodeValue(new CustomAttributeTypeProvider(asm));
110-
if (decoded.FixedArguments.Length == 1 &&
111-
decoded.FixedArguments[0].Value is int searchPath)
112-
{
113-
dllImportSearchPath = (DllImportSearchPath)searchPath;
114-
}
118+
decodedAttr = attr.DecodeValue(new CustomAttributeTypeProvider(asm));
115119
}
116120
}
121+
122+
DllImportSearchPath? dllImportSearchPath = default;
123+
if (decodedAttr.HasValue
124+
&& decodedAttr.Value.FixedArguments.Length == 1
125+
&& decodedAttr.Value.FixedArguments[0].Value is int searchPath)
126+
{
127+
dllImportSearchPath = (DllImportSearchPath)searchPath;
128+
}
129+
117130
ModuleData = new PInvokeModuleData(metadata.Module, dllImportSearchPath, declaringModule);
118131

119132
EntryPointName = metadata.Name;

src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,21 @@ private MsQuicApi(QUIC_API_TABLE* apiTable)
6464
#pragma warning disable CA1810 // Initialize all static fields in 'MsQuicApi' when those fields are declared and remove the explicit static constructor
6565
static MsQuicApi()
6666
{
67-
if (!NativeLibrary.TryLoad($"{Interop.Libraries.MsQuic}.{MinMsQuicVersion.Major}", typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out IntPtr msQuicHandle) &&
68-
!NativeLibrary.TryLoad(Interop.Libraries.MsQuic, typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle))
67+
bool loaded = false;
68+
IntPtr msQuicHandle;
69+
if (OperatingSystem.IsWindows())
70+
{
71+
// Windows ships msquic in the assembly directory.
72+
loaded = NativeLibrary.TryLoad(Interop.Libraries.MsQuic, typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle);
73+
}
74+
else
75+
{
76+
// Non-Windows relies on the package being installed on the system and may include the version in its name
77+
loaded = NativeLibrary.TryLoad($"{Interop.Libraries.MsQuic}.{MinMsQuicVersion.Major}", typeof(MsQuicApi).Assembly, null, out msQuicHandle) ||
78+
NativeLibrary.TryLoad(Interop.Libraries.MsQuic, typeof(MsQuicApi).Assembly, null, out msQuicHandle);
79+
}
80+
81+
if (!loaded)
6982
{
7083
// MsQuic library not loaded
7184
return;

src/mono/mono/metadata/native-library.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,10 +533,13 @@ netcore_probe_for_module (MonoImage *image, const char *file_name, int flags, Mo
533533

534534
ERROR_DECL (bad_image_error);
535535

536-
// Try without any path additions
536+
#if defined(HOST_ANDROID)
537+
// On Android, try without any path additions first. It is sensitive to probing that will always miss
538+
// and lookup for some libraries is required to use a relative path
537539
module = netcore_probe_for_module_variations (NULL, file_name, lflags, error);
538540
if (!module && !is_ok (error) && mono_error_get_error_code (error) == MONO_ERROR_BAD_IMAGE)
539541
mono_error_move (bad_image_error, error);
542+
#endif
540543

541544
// Check the NATIVE_DLL_SEARCH_DIRECTORIES
542545
for (int i = 0; i < pinvoke_search_directories_count && module == NULL; ++i) {
@@ -560,6 +563,16 @@ netcore_probe_for_module (MonoImage *image, const char *file_name, int flags, Mo
560563
g_free (mdirname);
561564
}
562565

566+
#if !defined(HOST_ANDROID)
567+
// Try without any path additions
568+
if (module == NULL)
569+
{
570+
module = netcore_probe_for_module_variations (NULL, file_name, lflags, error);
571+
if (!module && !is_ok (error) && mono_error_get_error_code (error) == MONO_ERROR_BAD_IMAGE)
572+
mono_error_move (bad_image_error, error);
573+
}
574+
#endif
575+
563576
// TODO: Pass remaining flags on to LoadLibraryEx on Windows where appropriate, see https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportsearchpath?view=netcore-3.1
564577

565578
if (!module && !is_ok (bad_image_error)) {

src/tests/Common/CoreCLRTestLibrary/PlatformDetection.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ public static class PlatformDetection
1010
{
1111
public static bool Is32BitProcess => IntPtr.Size == 4;
1212
public static bool Is64BitProcess => IntPtr.Size == 8;
13-
13+
1414
public static bool IsX86Process => RuntimeInformation.ProcessArchitecture == Architecture.X86;
1515
public static bool IsNotX86Process => !IsX86Process;
16+
17+
private static string _variant = Environment.GetEnvironmentVariable("DOTNET_RUNTIME_VARIANT");
18+
19+
public static bool IsMonoLLVMFULLAOT => _variant == "llvmfullaot";
1620
}
1721
}

src/tests/Common/testenvironment.proj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@
258258
<!-- Mono interpreter -->
259259
<_TestEnvFileLine Condition="'$(RuntimeVariant)' == 'monointerpreter'" Include="set MONO_ENV_OPTIONS=--interpreter" />
260260

261+
<_TestEnvFileLine Condition="'$(RuntimeVariant)' != ''" Include="set DOTNET_RUNTIME_VARIANT=$(RuntimeVariant)" />
262+
261263
<!-- CLR interpreter -->
262264
<_TestEnvFileLine Condition="'$(Scenario)' == 'clrinterpreter'" Include="set COMPlus_Interpret=%2A" /> <!-- %2A is asterisk / wildcard -->
263265
<_TestEnvFileLine Condition="'$(Scenario)' == 'clrinterpreter'" Include="set COMPlus_InterpreterHWIntrinsicsIsSupportedFalse=1" />
@@ -273,6 +275,8 @@
273275
<!-- Mono interpreter -->
274276
<_TestEnvFileLine Condition="'$(RuntimeVariant)' == 'monointerpreter'" Include="export MONO_ENV_OPTIONS=--interpreter" />
275277

278+
<_TestEnvFileLine Condition="'$(RuntimeVariant)' != ''" Include="export DOTNET_RUNTIME_VARIANT=$(RuntimeVariant)" />
279+
276280
<!-- Use Mono LLVM JIT when JIT-compiling the non-AOT-compiled parts of the runtime tests -->
277281
<_TestEnvFileLine Condition="'$(RuntimeVariant)' == 'llvmaot'" Include="export MONO_ENV_OPTIONS=--llvm" />
278282

src/tests/Directory.Build.targets

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,13 +537,17 @@
537537
<_UsingDefaultForHasRuntimeOutput>false</_UsingDefaultForHasRuntimeOutput>
538538
</PropertyGroup>
539539

540+
<ItemGroup Condition="'$(TestBuildMode)' == 'nativeaot'">
541+
<IlcReference Include="$(TargetingPackPath)/*.dll" />
542+
</ItemGroup>
543+
540544
<Import Project="$(CoreCLRBuildIntegrationDir)Microsoft.NETCore.Native.targets" Condition="'$(TestBuildMode)' == 'nativeaot'" />
541545

542546
<Target Name="BuildNativeAot"
543547
DependsOnTargets="Build;LinkNativeIfBuildAndRun" />
544548

545549
<Target Name="LinkNativeIfBuildAndRun"
546-
Condition="'$(CLRTestTargetUnsupported)' != 'true' and '$(CLRTestKind)' == 'BuildAndRun'"
550+
Condition="'$(_WillCLRTestProjectBuild)' == 'true' and '$(CLRTestKind)' == 'BuildAndRun'"
547551
DependsOnTargets="ComputeResolvedFilesToPublishList;LinkNative" />
548552

549553
</Project>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.IO;
6+
using System.Reflection;
7+
using System.Runtime.InteropServices;
8+
using Xunit;
9+
10+
public class DllImportSearchPathsTest
11+
{
12+
private static string Subdirectory => Path.Combine(NativeLibraryToLoad.GetDirectory(), "subdirectory");
13+
14+
[Fact]
15+
public static void AssemblyDirectory_NotFound()
16+
{
17+
// Library should not be found in the assembly directory
18+
Assert.Throws<DllNotFoundException>(() => NativeLibraryPInvoke.Sum(1, 2));
19+
}
20+
21+
public static bool CanLoadAssemblyInSubdirectory =>
22+
!TestLibrary.Utilities.IsNativeAot && !TestLibrary.PlatformDetection.IsMonoLLVMFULLAOT;
23+
24+
[ConditionalFact(nameof(CanLoadAssemblyInSubdirectory))]
25+
public static void AssemblyDirectory_Found()
26+
{
27+
// Library should be found in the assembly directory
28+
var assembly = Assembly.LoadFile(Path.Combine(Subdirectory, $"{nameof(DllImportSearchPathsTest)}.dll"));
29+
var type = assembly.GetType(nameof(NativeLibraryPInvoke));
30+
var method = type.GetMethod(nameof(NativeLibraryPInvoke.Sum));
31+
32+
int sum = (int)method.Invoke(null, new object[] { 1, 2 });
33+
Assert.Equal(3, sum);
34+
}
35+
36+
[Fact]
37+
[PlatformSpecific(TestPlatforms.Windows)]
38+
public static void AssemblyDirectory_Fallback_Found()
39+
{
40+
string currentDirectory = Environment.CurrentDirectory;
41+
try
42+
{
43+
Environment.CurrentDirectory = Subdirectory;
44+
45+
// Library should not be found in the assembly directory, but should fall back to the default OS search which includes CWD on Windows
46+
int sum = NativeLibraryPInvoke.Sum(1, 2);
47+
Assert.Equal(3, sum);
48+
}
49+
finally
50+
{
51+
Environment.CurrentDirectory = currentDirectory;
52+
}
53+
}
54+
}
55+
56+
public class NativeLibraryPInvoke
57+
{
58+
public static int Sum(int a, int b)
59+
{
60+
return NativeSum(a, b);
61+
}
62+
63+
[DllImport(NativeLibraryToLoad.Name)]
64+
[DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)]
65+
static extern int NativeSum(int arg1, int arg2);
66+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<Compile Include="*.cs" />
7+
<Compile Include="../NativeLibrary/NativeLibraryToLoad/NativeLibraryToLoad.cs" />
8+
<CMakeProjectReference Include="../NativeLibrary/NativeLibraryToLoad/CMakeLists.txt" />
9+
</ItemGroup>
10+
11+
<Target Name="SetUpSubdirectory" AfterTargets="CopyNativeProjectBinaries">
12+
<PropertyGroup>
13+
<NativeLibrarySubdirectory>$(OutDir)/subdirectory</NativeLibrarySubdirectory>
14+
<FileNameSuffix>-in-subdirectory</FileNameSuffix>
15+
</PropertyGroup>
16+
<ItemGroup>
17+
<_FilesToCopy Include="$(OutDir)/$(TargetName).dll" />
18+
<_FilesToMove Include="$(OutDir)/libNativeLibrary.*" />
19+
<_FilesToMove Include="$(OutDir)/NativeLibrary.*" />
20+
</ItemGroup>
21+
<Copy SourceFiles="@(_FilesToCopy)" DestinationFiles="@(_FilesToCopy -> '$(NativeLibrarySubdirectory)/%(Filename)%(Extension)')" />
22+
<Move SourceFiles="@(_FilesToMove)" DestinationFiles="@(_FilesToMove -> '$(NativeLibrarySubdirectory)/%(Filename)%(Extension)')" />
23+
</Target>
24+
</Project>

src/tests/Interop/NativeLibrary/API/GetMainProgramHandleTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static void GloballyLoadedLibrarySymbolsVisibleFromMainProgramHandle()
4545
// On non-Windows platforms, symbols from globally loaded shared libraries will also be discoverable.
4646
// Globally loading symbols is not the .NET default, so we use a call to dlopen in native code
4747
// with the right flags to test the scenario.
48-
IntPtr handle = LoadLibraryGlobally(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), NativeLibraryToLoad.GetLibraryFileName("GloballyLoadedNativeLibrary")));
48+
IntPtr handle = LoadLibraryGlobally(Path.Combine(NativeLibraryToLoad.GetDirectory(), NativeLibraryToLoad.GetLibraryFileName("GloballyLoadedNativeLibrary")));
4949

5050
try
5151
{
@@ -64,7 +64,7 @@ public static void InvalidSymbolName_Fails()
6464
// On non-Windows platforms, symbols from globally loaded shared libraries will also be discoverable.
6565
// Globally loading symbols is not the .NET default, so we use a call to dlopen in native code
6666
// with the right flags to test the scenario.
67-
IntPtr handle = LoadLibraryGlobally(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), NativeLibraryToLoad.GetLibraryFileName("GloballyLoadedNativeLibrary")));
67+
IntPtr handle = LoadLibraryGlobally(Path.Combine(NativeLibraryToLoad.GetDirectory(), NativeLibraryToLoad.GetLibraryFileName("GloballyLoadedNativeLibrary")));
6868

6969
try
7070
{
@@ -83,7 +83,7 @@ public static void GloballyLoadedLibrarySymbolsVisibleFromMainProgramHandle_Mang
8383
// On non-Windows platforms, symbols from globally loaded shared libraries will also be discoverable.
8484
// Globally loading symbols is not the .NET default, so we use a call to dlopen in native code
8585
// with the right flags to test the scenario.
86-
IntPtr handle = LoadLibraryGlobally(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), NativeLibraryToLoad.GetLibraryFileName("GloballyLoadedNativeLibrary")));
86+
IntPtr handle = LoadLibraryGlobally(Path.Combine(NativeLibraryToLoad.GetDirectory(), NativeLibraryToLoad.GetLibraryFileName("GloballyLoadedNativeLibrary")));
8787

8888
try
8989
{

src/tests/Interop/NativeLibrary/API/NativeLibraryTests.cs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class NativeLibraryTests : IDisposable
1717
public NativeLibraryTests()
1818
{
1919
assembly = System.Reflection.Assembly.GetExecutingAssembly();
20-
testBinDir = Path.GetDirectoryName(assembly.Location);
20+
testBinDir = NativeLibraryToLoad.GetDirectory();
2121
libFullPath = NativeLibraryToLoad.GetFullPath();
2222
}
2323

@@ -133,11 +133,19 @@ public void LoadLibraryFullPathWithoutNativePrefixOrSuffix_WithAssembly_Failure(
133133
public void LoadSystemLibrary_WithSearchPath()
134134
{
135135
string libName = "url.dll";
136-
// Calls on a valid library from System32 directory
136+
// Library should be found in the system directory
137137
EXPECT(LoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.System32));
138138
EXPECT(TryLoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.System32));
139139

140-
// Calls on a valid library from application directory
140+
// Library should not be found in the assembly directory and should be found in the system directory
141+
EXPECT(LoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.System32));
142+
EXPECT(TryLoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.System32));
143+
144+
// Library should not be found in the assembly directory, but should fall back to the default OS search which includes CWD on Windows
145+
EXPECT(LoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.AssemblyDirectory));
146+
EXPECT(TryLoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.AssemblyDirectory));
147+
148+
// Library should not be found in application directory
141149
EXPECT(LoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.ApplicationDirectory), TestResult.DllNotFound);
142150
EXPECT(TryLoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.ApplicationDirectory), TestResult.ReturnFailure);
143151
}
@@ -165,6 +173,40 @@ public void LoadLibrary_UsesFullPath_EvenWhen_AssemblyDirectory_Specified()
165173
EXPECT(TryLoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.AssemblyDirectory), TestResult.ReturnFailure);
166174
}
167175

176+
[Fact]
177+
public void LoadLibrary_AssemblyDirectory()
178+
{
179+
string suffix = "-in-subdirectory";
180+
string libName = $"{NativeLibraryToLoad.Name}{suffix}";
181+
182+
string subdirectory = Path.Combine(testBinDir, "subdirectory");
183+
184+
if (!TestLibrary.Utilities.IsNativeAot && !TestLibrary.PlatformDetection.IsMonoLLVMFULLAOT)
185+
{
186+
// Library should be found in the assembly directory
187+
Assembly assemblyInSubdirectory = Assembly.LoadFile(Path.Combine(subdirectory, $"{Path.GetFileNameWithoutExtension(assembly.Location)}{suffix}.dll"));
188+
EXPECT(LoadLibrary_WithAssembly(libName, assemblyInSubdirectory, DllImportSearchPath.AssemblyDirectory));
189+
EXPECT(TryLoadLibrary_WithAssembly(libName, assemblyInSubdirectory, DllImportSearchPath.AssemblyDirectory));
190+
}
191+
192+
if (OperatingSystem.IsWindows())
193+
{
194+
string currentDirectory = Environment.CurrentDirectory;
195+
try
196+
{
197+
Environment.CurrentDirectory = subdirectory;
198+
199+
// Library should not be found in the assembly directory, but should fall back to the default OS search which includes CWD on Windows
200+
EXPECT(LoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.AssemblyDirectory));
201+
EXPECT(TryLoadLibrary_WithAssembly(libName, assembly, DllImportSearchPath.AssemblyDirectory));
202+
}
203+
finally
204+
{
205+
Environment.CurrentDirectory = currentDirectory;
206+
}
207+
}
208+
}
209+
168210
[Fact]
169211
public void Free()
170212
{

src/tests/Interop/NativeLibrary/API/NativeLibraryTests.csproj

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,17 @@
1515
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
1616
<CMakeProjectReference Include="../NativeLibraryToLoad/CMakeLists.txt" />
1717
</ItemGroup>
18+
19+
<Target Name="SetUpSubdirectory" AfterTargets="CopyNativeProjectBinaries">
20+
<PropertyGroup>
21+
<NativeLibrarySubdirectory>$(OutDir)/subdirectory</NativeLibrarySubdirectory>
22+
<FileNameSuffix>-in-subdirectory</FileNameSuffix>
23+
</PropertyGroup>
24+
<ItemGroup>
25+
<AssembliesToCopy Include="$(OutDir)/libNativeLibrary.*" />
26+
<AssembliesToCopy Include="$(OutDir)/NativeLibrary.*" />
27+
<AssembliesToCopy Include="$(OutDir)/$(TargetName).dll" />
28+
</ItemGroup>
29+
<Copy SourceFiles="@(AssembliesToCopy)" DestinationFiles="@(AssembliesToCopy -> '$(NativeLibrarySubdirectory)/%(Filename)$(FileNameSuffix)%(Extension)')" />
30+
</Target>
1831
</Project>

src/tests/Interop/NativeLibrary/Callback/CallbackTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ private IntPtr ResolveDllImport(string libraryName, Assembly asm, DllImportSearc
9999
if (string.Equals(libraryName, NativeLibraryToLoad.InvalidName))
100100
{
101101
Assert.Equal(DllImportSearchPath.System32, dllImportSearchPath);
102-
return NativeLibrary.Load(NativeLibraryToLoad.Name, asm, null);
102+
return NativeLibrary.Load(NativeLibraryToLoad.GetFullPath(), asm, null);
103103
}
104104

105105
return IntPtr.Zero;

0 commit comments

Comments
 (0)