简体   繁体   中英

DLL in NuGet package not appearing in build output folder

We have a NuGet package that was created by ourselves and is hosted on an in-house repo. We've been using it for several years in a.Net Framework 4.x solution. The package contains a.Net4.x assembly (a class library, referenced by code in the solution), two "native" DLLs, and a handful of.c files. When the solution builds, every file in the package gets copied to the build output folder, which is what we expect.

I've now migrated this solution to.Net6 and referencing the same package, but the build behaviour is different. Here, the solution builds successfully but none of the files in the package get copied to the build output folder. Instead, the two native DLLs and.c files get copied to the root folder of the referencing project (also showing up in the VS solution explorer window). The.Net assembly (TspAdqAcquisition.dll) does not appear in the project root folder, or anywhere else for that matter.

What's going on?

This is the nuspec file (from the "library" solution where the Tsp...dll and other files reside):

<?xml version="1.0" encoding="utf-8"?>
<package >
  <metadata minClientVersion="2.5">
    ....
  </metadata>

  <files>    
    <file src="x64\Release\*.c" target="build" />
    <file src="x64\Release\glew64.dll" target="build\glew64.dll" />
    <file src="x64\Release\glut64.dll" target="build\glut64.dll" />
    <file src="x64\Release\TspAdqAcquisition.dll" target="lib\net451\TspAdqAcquisition.dll" />
    <file src="x64\Release\TspAdqAcquisition.dll" target="lib\net\TspAdqAcquisition.dll" />
    <file src="x64\Release\TspAdqAcquisition.dll" target="lib\net6.0\TspAdqAcquisition.dll" />
    <file src="x64\Release\TspAdqAcquisition.dll" target="lib\net6.0-windows10\TspAdqAcquisition.dll" />
    <file src="x64\Release\TspAdqAcquisition.dll" target="lib\net6.0-windows11\TspAdqAcquisition.dll" />
  </files>
</package>

Edit I've figured out why the two native DLLs and.c files weren't being copied to the build output folder. The NuGet package in question is referenced by a class library project (net6.0 TFM rather than net6.0-windows), so these particular files were ending up in a separate \net6.0\ build output folder, rather than the \net6.0-windows\ build output folder that the rest of the solution ends up in. Once I'd referenced that class library project by one of the WPF projects, these files appeared in the correct build output folder.

However the TspAdqAcquisition.dll assembly still isn't being copied to (either) build output folder.

Edit 2 I'm now able to get the TspAdqAcquisition.dll assembly to copy to the build output folder by including this line in the project file:

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

I had to put this in the WPF project file to ensure that the DLL is copied to the correct (\net6.0-windows) build output folder. If I add the above line to the class library project file referencing the NuGet package then the DLL ends up in the wrong (\net6.0) build output folder.

It's all starting to feel a bit hacky for my liking...

My last remaining question then is whether it's possible to prevent those native DLLs and.c files from being "unpackaged" into the project folder and cluttering up the solution explorer window? Why doesn't this happen in VS2019?

It seems you don't have a.targets file in the nuget package. I'm not sure whether that's the "normal" way of how this should be done, but that's how I copy native binaries to the output.

So one possible way to get this to work correctly, is to create a <packagename>.targets file in the build folder of the nuget with content such as:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="CopyFilesToTargetDirectory_MyPackageName" BeforeTargets="Build">
    <ItemGroup>
            <FilesForTargetDirectory_MyPackageName Include="$(MSBuildThisFileDirectory)\..\tools\**\*.*" />
    </ItemGroup>
    <PropertyGroup>
            <TargetDirectory_MyPackageName Condition="'$(TargetDirectory_MyPackageName)' == ''">$(TargetDir)</TargetDirectory_MyPackageName>
    </PropertyGroup>
    <Copy SourceFiles="@(FilesForTargetDirectory_MyPackageName)" 
          DestinationFolder="$(TargetDirectory_MyPackageName)\%(RecursiveDir)"
          SkipUnchangedFiles="true" />
  </Target>
</Project>

and then, move the native libraries from the build folder to either the tools folder (as in the example code above) or the lib\native folder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM