'How can i make dll.config to be part of Nuget package

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.



Solution 1:[1]

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.

Solution 2:[2]

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

Solution 3:[3]

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

Solution 4:[4]

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>

Solution 5:[5]

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://docs.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://docs.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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tim Calladene
Solution 2 prudviraj
Solution 3 Tylor
Solution 4 decocijo
Solution 5