Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to place dlls for unmanaged libraries?

I am trying to create a Nuget package for a library that depends on ghostscript and therefore references gsdll32.dll - an unmanaged library. I can't just included that a standard dll reference. Where do I put this in the nuget directory structure?

like image 997
George Mauer Avatar asked Apr 17 '12 20:04

George Mauer


People also ask

Is dll managed or unmanaged?

dll is definitely unmanaged - it's part of Windows. If you want to check, try to add the file as a reference to your project - if it adds ok, it's managed.

How do I add a dll to C++ project in Visual Studio?

On the menu bar, choose File > New > Project to open the New Project dialog box. In the left pane of the New Project dialog box, select Installed > Visual C++ > Windows Desktop. In the center pane, select Dynamic-Link Library (DLL).

How do I link a dll in Visual Studio?

On Windows you do not link with a . dll file directly – you must use the accompanying . lib file instead. To do that go to Project -> Properties -> Configuration Properties -> Linker -> Additional Dependencies and add path to your .


2 Answers

Add a build folder to the package and, if the package for example has the id MyPackage, add a MSBuild target file called MyPackage.targets to this folder. It is important that the .targets file has the same name as the .nuspec file. In the .nuspec file you must have a section like this:

<files>     <file src="lib\*.*" target="lib" />     <file src="build\MyPackage.targets" target="build" /> </files> 

This will add an MSBuild element in the project file pointing to the .targets file.

Furthermore, to only register the managed dlls, add a section like this:

<references>     <reference file="MyManaged.dll" /> </references> 

The .targets file should look something like this:

<?xml version="1.0" encoding="utf-8"?>  <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">    <Target Name="CopyMyPackageFiles" AfterTargets="AfterBuild">      <ItemGroup>        <MyPackageFiles Include="$(MSBuildThisFileDirectory)..\lib\*.*"/>      </ItemGroup>      <Copy SourceFiles="@(MyPackageFiles)" DestinationFolder="$(OutputPath)" >      </Copy>    </Target>  </Project> 

Now, all files - including unmanaged files - will be copied to the project output folder (e.g. \bin\debug) after the build.

like image 109
Lars Michael Avatar answered Sep 19 '22 07:09

Lars Michael


The above reference can work, but it actually modifies your post build event to push files over, which may not actually fix your issue if you have the situation we did.

The issue we were having was a dependent DLL could not be registered, but had to exist side by side with another DLL which needed to be registered by nuget so it needed to exist in the lib directory but not be registered.

The nuspec reference now allows you to specify which DLLs in the lib directory get explicitly registered in the visual studio project now, you simply need to add into your nuspec file in the metadata area an explicit references list (if this does not exist the default behavior of nuget is to attempt to register everything under lib).

Here is an example nuspec file of what I mean:

<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">     <metadata>         <id>SomePackageID</id>         <version>1.0.1</version>         <title>Some Package Title</title>         <authors>Some Authors</authors>         <requireLicenseAcceptance>false</requireLicenseAcceptance>         <description>Blah blah blah.</description>         <references>             <reference file="ceTe.DynamicPDF.Rasterizer.20.x86.dll" />                   </references>     </metadata>     <files>         <file src="\\SomeNetworkLocation\ceTe.DynamicPDF.Rasterizer.20.x86.dll" target="lib\ceTe.DynamicPDF.Rasterizer.20.x86.dll" />         <file src="\\SomeNetworkLocation\DPDFRast.x86.dll" target="lib\DPDFRast.x86.dll" />     </files> </package> 

As you can see, ceTe.DynamicPDF.Rasterizer.20.x86.dll needs to be registered, but DPDFRast.x86.dll simply needs to exist in that directory to support the other DLL and won't be registered but through some dynamic referencing magic will ultimately be copied over into the destination bin directory anyway because visual studio sees that the first DLL is dependent upon the second.

Here is the original nuspec reference.

like image 29
James Eby Avatar answered Sep 17 '22 07:09

James Eby