5

Since dll.config is not supported by .NET and while creating nuget packages dll.config are not part of the package.

Is there a way that i can have dll.config as part of the nuget package? If someone consumes my nuget package they should get both the *.dll and *.dll.config file in their drop location

Would like some suggestions if its possible.

StackOverflowVeryHelpful
  • 2,347
  • 8
  • 34
  • 46

5 Answers5

3

If you're using an SDK style project, and assuming that you've previously added an Application Configuration File to the project (App.Config), then just add the following to your .csproj file:

<ItemGroup>
  <None Update="App.config">
    <Pack>True</Pack>
    <PackagePath>lib\$(TargetFramework)\$(AssemblyName).dll.config</PackagePath>
  </None>
</ItemGroup>

I used this recently to automatically include assembly binding redirects when the package is deployed.

Tim Calladene
  • 107
  • 12
1

Have Tried above requirement and able to package dll config , try as below You can bundle dll config files along with you dll files just use file tag to do

<file src="path\to\dllconfigfile\*.*" target="lib\net35" />

click here -- > include files in nuget package

prudviraj
  • 3,634
  • 2
  • 16
  • 22
0

If you use VS2015, then try Nuget Package Explorer, it has friendly GUI Interface, and support files dropping. You can drop the files in there. enter image description here

Tylor
  • 33
  • 6
  • I've tried this and the .dll.config isn't copied to the output folder of the project referencing the package. – SuperJMN Dec 10 '21 at 11:06
0

What worked for me:

In short: add a .props and .targets file to the nuget package that get executed in the project that consumes the nuget package and copies the .config file to the output directory:

I added a <PackageId>.props and <PackageId>.targets file (replace <PackageId> with the real name of the package):

<PackageId>.props:

<Project>
    <ItemGroup>
        <ConfigFiles Include="$(MSBuildThisFileDirectory)../contentFiles/any/any/<PackageId>.config" />
    </ItemGroup>
</Project>

<PackageId>.targets:

<Project>
    <Target Name="CopyConfigFiles" BeforeTargets="Build" Condition="!$(TargetFramework.StartsWith('netstandard'))">
        <Copy SourceFiles="@(ConfigFiles)" DestinationFolder="$(TargetDir)" />
    </Target>
</Project>

and then add the .props and .targets file to the build and buildMultiTargeting folders of the nuget package, e.g. by adding the following to the .csproj file:

<ItemGroup>
  <None Include="App.config" Pack="true"
    PackagePath="contentFiles\any\any\$(AssemblyTitle).dll.config" />
</ItemGroup>

<Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
  <ItemGroup>
    <None Include="$(PackageId).props" Pack="true" PackagePath="build" />
    <None Include="$(PackageId).props" Pack="true" PackagePath="buildMultiTargeting" />
    <None Include="$(PackageId).targets" Pack="true" PackagePath="build" />
    <None Include="$(PackageId).targets" Pack="true" PackagePath="buildMultiTargeting" />
  </ItemGroup>
</Target>

decocijo
  • 908
  • 7
  • 19
0

VS 2019, SDK Style library project.

Don't know why this was necessary. Seems like it should be a default function. But this worked for me.

<ItemGroup>
  <None Include="$(OutputPath)\$(AssemblyName).dll.config" Pack="True" PackagePath="lib\$(TargetFramework)" />
</ItemGroup>

Update 4/11/22

This was for an SDK-Style .NET Framework library. The relevant portions of the project file are as follows:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Library</OutputType>
    <RootNamespace>...</RootNamespace>
    <TargetFramework>net452</TargetFramework>
    <Platforms>AnyCPU</Platforms>
    <NoWarn>1701;1702;1591</NoWarn>
    
    <AssemblyTitle>...</AssemblyTitle>
    <Description>...</Description>
    <Company>...</Company>
    <Copyright>...</Copyright>
    <Version>...</Version>
  </PropertyGroup>
  
  <Import Project="$(MSBuildProjectDirectory)\Package.targets" />
  ...
  <ItemGroup>
    <PackageReference Include="Microsoft.SourceLink.GitLab" Version="1.1.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
    </PackageReference>
  </ItemGroup>
  <ItemGroup>
    <Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
  </ItemGroup>
</Project>

You can see where the project file includes package.targets, below. This is where all the NuGet packaging code resides.

This package includes both the Release and Debug builds of the library with a .targets include to copy in the appropriate version for the build. For this reason, the OutputPath is fixed at lines 45-59.

What you are looking for is at lines 108-114:

<!--****************************************************************************
* NuGet Package Configuration
*****************************************************************************-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  
  <PropertyGroup>
    <!--=======================================================================-->
    <!-- T4 template used to create `build\{tfm}\$(AssemblyName).targets` for  -->
    <!-- inclusion in the `.nupkg` file. Requires `dotnet-t4` being installed. -->
    <!--=======================================================================-->
    <BuildTargetsFile>Build.targets.tt</BuildTargetsFile>
    
    <!--===========================================================================-->
    <!-- Normally set `true` so deterministic Source Link URLs are generated and   -->
    <!-- all source requests will go to the remote repository. Setting this to     -->
    <!-- `false` (debugging only) will look for the source files in the local      -->
    <!-- directory where this library was built before looking to the remote repo. -->
    <!--===========================================================================-->
    <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
    
    <!--====================================-->
    <!-- Temporary folder where other tools -->
    <!-- puts files required by this file.  -->
    <!--====================================-->
    <TempFilesPath>$(SolutionDir)\output</TempFilesPath>
  </PropertyGroup>
  
  <ItemGroup>
    <!--================================================================-->
    <!-- Change Source Link host to proxy where GitLab repo URLs are    -->
    <!-- converted to GitLab API requests with required authentication. -->
    <!--================================================================-->
    <SourceLinkGitLabHost Include="gitlab.com" ContentUrl="https://gitlabproxy.loc" />
  </ItemGroup>
  
  <!--========================================================-->
  <!-- `Version.targets` is updated by `npm version` command. -->
  <!--========================================================-->
  <Import Project="$(MSBuildProjectDirectory)\Version.targets" />

  <!--==============================================-->
  <!-- Fix the output paths so we can build a NuGet -->
  <!-- package with both Release and Debug builds.  -->
  <!--==============================================-->
  <PropertyGroup>
    <DebugOutputPath>bin\Debug</DebugOutputPath>
  </PropertyGroup>
  <Choose>
    <When Condition="'$(Configuration)' == 'Debug'">
      <PropertyGroup>
        <OutputPath>$(DebugOutputPath)</OutputPath>
      </PropertyGroup>
    </When>
    <When Condition="'$(Configuration)' == 'Release'">
      <PropertyGroup>
        <OutputPath>bin\Release</OutputPath>
      </PropertyGroup>
    </When>
  </Choose>

  <!--==================================================================-->
  <!-- Nuget Package can only be created in Release mode, using `dotnet -->
  <!-- pack`, after the Debug build, and must include the Debug output. -->
  <!--                                                                  -->
  <!-- Title tag missing from UI.                                       -->
  <!-- https://github.com/dotnet/project-system/issues/2937             -->
  <!--==================================================================-->
  <PropertyGroup>
    <Title>$(AssemblyTitle)</Title>
    <Authors>$(Company)</Authors>
    
    <!--===========================================================-->
    <!-- Include `.pdb` file in `.nupkg` so it will be downloaded  -->
    <!-- with the `.dll`. GitLab does not provide a symbol server. -->
    <!-- https://gitlab.com/gitlab-org/gitlab/-/issues/342157      -->
    <!--===========================================================-->
    <AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
    <!--<IncludeSymbols>true</IncludeSymbols>-->
    <!--<SymbolPackageFormat>snupkg</SymbolPackageFormat>-->
  </PropertyGroup>
  
  <!--===========================================================-->
  <!-- Build Intellisense file in Release mode. This is required -->
  <!-- for `pack` to include the file in the NuGet package.      -->
  <!--===========================================================-->
  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
  </PropertyGroup>
  
  <!--==============================================================================-->
  <!-- Add files to include in `.nupkg` file before packing.                        -->
  <!--                                                                              -->
  <!-- These are temporary files so we don't want them referenced in the project    -->
  <!-- but only included files can be packed (`Pack="True"` is ignored for `<None   -->
  <!-- Remove="..."/>`). To keep the references out of the project, these files     -->
  <!-- are only included here.                                                      -->
  <!--                                                                              -->
  <!-- https://learn.microsoft.com/en-us/nuget/reference/msbuild-targets#pack-target -->
  <!--==============================================================================-->
  <Target Name="BeforePack" BeforeTargets="_GetPackageFiles">
    
    <!--===============================================================-->
    <!-- Pack is only allowed in Release build. Debug build must have  -->
    <!-- already been done so debug assembly can be added to `.nupkg`. -->
    <!--===============================================================-->
    <Error Condition="'$(Configuration)' != 'Release'" Text="`pack` target is only available in 'Release' mode." />
    
    <!--==================================================-->
    <!-- This copies the library config file to the       -->
    <!-- package. Seems like this shouldn't be necessary. -->
    <!--==================================================-->
    <ItemGroup Condition="Exists('$(OutputPath)\$(AssemblyName).dll.config')">
      <None Include="$(OutputPath)\$(AssemblyName).dll.config" Pack="True" PackagePath="lib\$(TargetFramework)" />
    </ItemGroup>
    
    <!--=================================================-->
    <!-- Pack debug assembly files into `libdbg` folder. -->
    <!--=================================================-->
    <ItemGroup>
      <None Include="$(DebugOutputPath)\$(TargetFramework)\$(AssemblyName).dll" Pack="True" PackagePath="libdbg\$(TargetFramework)" />
      <None Include="$(DebugOutputPath)\$(TargetFramework)\$(AssemblyName).pdb" Pack="True" PackagePath="libdbg\$(TargetFramework)" />
    </ItemGroup>
    
    <!--==========================================-->
    <!-- Copy Intellisense file created from      -->
    <!-- Doxygen output over the file VS created. -->
    <!--==========================================-->
    <copy Condition="Exists('$(TempFilesPath)\$(AssemblyName).xml')" SourceFiles="$(TempFilesPath)\$(AssemblyName).xml" DestinationFolder="$(OutputPath)" />

    <!--==================================================-->
    <!-- Create the `build\{tfm}\$(AssemblyName).targets` -->
    <!-- file from T4 template and add to package.        -->
    <!--                                                  -->
    <!-- https://github.com/nogic1008/T4Sample            -->
    <!--==================================================-->
    <PropertyGroup>
      <BuildTargetsPath>$(IntermediateOutputPath)\$(AssemblyName).targets</BuildTargetsPath>
    </PropertyGroup>
    <Exec WorkingDirectory="$(ProjectDir)" 
                   Command="dotnet t4 &quot;$(BuildTargetsFile)&quot; -o &quot;$(BuildTargetsPath)&quot; -pAssemblyName=&quot;$(AssemblyName)&quot;" />
    <ItemGroup>
      <None Include="$(BuildTargetsPath)" Pack="True" PackagePath="build\$(TargetFramework)\" />
    </ItemGroup>
  </Target>
    
  <!--=============================================-->
  <!-- Source Link                                 -->
  <!-- https://github.com/dotnet/sourcelink#gitlab -->
  <!--=============================================-->
  <ItemGroup>
    <!--======================================================================================================-->
    <!-- Assembly Info generated into `AssemblyInfo.cs` and embedded in `.dll`.                               -->
    <!-- https://learn.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props#assembly-attribute-properties -->
    <!--======================================================================================================-->
    <EmbeddedFiles Include="$(GeneratedAssemblyInfoFile)" />
  </ItemGroup>
  <PropertyGroup>
    <PublishRepositoryUrl>true</PublishRepositoryUrl>
    
    <!--=================================================-->
    <!-- Embed generated `AssemblyInfo.cs`.              -->
    <!-- https://github.com/dotnet/sourcelink/issues/572 -->
    <!--=================================================-->
    <!--<EmbedUntrackedSources>true</EmbedUntrackedSources>-->
    <TargetFrameworkMonikerAssemblyAttributesPath>$([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))</TargetFrameworkMonikerAssemblyAttributesPath>
  </PropertyGroup>
</Project>

Hope it helps.

Update 4/15/22

Ok, my bad. It turns out, this works to package the .dll.config file in the .nupkg file but, at build time, it is not copied to the consuming project bin folder.

Referring to the file above, replacing this:

    <!--==================================================-->
    <!-- This copies the library config file to the       -->
    <!-- package. Seems like this shouldn't be necessary. -->
    <!--==================================================-->
    <ItemGroup Condition="Exists('$(OutputPath)\$(AssemblyName).dll.config')">
      <None Include="$(OutputPath)\$(AssemblyName).dll.config" Pack="True" PackagePath="lib\$(TargetFramework)" />
    </ItemGroup>

with this, fixes it:

    <!--==================================================================-->
    <!-- This includes the library config file in th package file and     -->
    <!-- copies it to the consumer bin folder. Seems like this shouldn't  -->
    <!-- be necessary.                                                    -->
    <!--                                                                  -->
    <!-- https://github.com/dotnet/sdk/issues/3249#issuecomment-662562709 -->
    <!--==================================================================-->
    <ItemGroup Condition="Exists('App.config')">
      <None Include             = "App.config" 
            Pack                = "true" 
            PackagePath         = "contentFiles/any/$(TargetFramework)/$(TargetFileName).config"
            PackageCopyToOutput = "true">
      </None>
    </ItemGroup>

One note of caution, however. While this does copy the .dll.config file to the bin folder of the consuming project, it will not do so in a transitive way. That is to say, if the package is consumed by project B which is consumed by project A, the .dll.config of the package will be copied to the bin folder of project B but NOT to the bin folder of project A, even though the .dll and .pdb files will be. The package must be installed to project A for the config file copy to work.

So far, I have not found a solution to this.

sthames42
  • 888
  • 8
  • 19
  • doesn't work for me. Can you share your whole csproj info and the dotnet version you are using? – togarha Apr 11 '22 at 15:53
  • @togarha, sorry for the delay. Didn't see your message. I will try to post by COB if you still need this. – sthames42 Apr 11 '22 at 19:32
  • Thanks @sthames42, I see it needs dotnet-t4 to work, I'll try some other solutions without any external plugin/tool needed. If I cannot get it working, then I'll try this one. – togarha Apr 13 '22 at 16:24
  • @togarha, you only need dotnet-t4 if you want to include the Debug dll file in the .nupkg file. If all you want is to include the .dll.config, you can strip all that out as all you really need is lines 118-114 in the "BeforePack" target. – sthames42 Apr 14 '22 at 14:29
  • I tried it just adding the `Package.targets` file with the BeforePack section and only the config section and it didn't work for me. If I try the original option, nothing happens, only the dll is added to the package. If I try the updated solution, I get a `contentFiles/any/_/.config` file inside the package. My project is a multitarget project, so my dll output path is something like `bin/Release/net5.0/`, and I correctly have the dll.config copied there, but I can't get it into the `lib/net5.0/` nupkg folder – togarha Apr 19 '22 at 09:45
  • to be more exact, I have the full description of my problem at the following link: https://stackoverflow.com/questions/71829288/error-adding-app-config-file-to-the-nuget-package – togarha Apr 19 '22 at 09:46
  • 1
    @togarha, took a look at your problem and mine is similar in that my .nupkg file includes multiple versions of the lib. Hardcoding is really the only way to accomplish it. As you can see, I address this with a lot of documentation. You might consider using a .nuspec file but that is outside my experience. – sthames42 Apr 20 '22 at 13:55