6

Roslyn 打包自定义的文件到 NuGet 包

 3 years ago
source link: https://lindexi.gitee.io/post/Roslyn-%E6%89%93%E5%8C%85%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84%E6%96%87%E4%BB%B6%E5%88%B0-NuGet-%E5%8C%85.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Roslyn 打包自定义的文件到 NuGet 包

在使用 sdk 格式的项目文件支持快速进行打包,但使用这个方式打包的时候将默认只带程序集输出文件,而没有带依赖的文件。本文告诉大家如何在打包的时候加上需要放在包里面的文件

VisualStudio 使用新项目格式快速打出 Nuget 包 告诉大家快速打包的方法,但有时候我需要将本地的一些资源或依赖也放在包里面,此时就需要用到下面的方法

在项目里面引用的资源,可以通过在引用的时候添加 Pack 属性设置打包,使用 PackagePath 属性设置打包的时候放在包里面的哪个文件夹

例如将项目里面引用的 林德熙是逗比.txt 打包放在 lib\doubi 文件夹里面,可以这样写

<None Include="林德熙是逗比.txt"
                  Pack="True"
                  PackagePath="\lib\doubi\" />

注意需要将 None 放在 ItemGroup 里面,请看代码

    <ItemGroup>
        <None Include="林德熙是逗比.txt"
              Pack="True"
              PackagePath="\lib\doubi\" />	
    </ItemGroup>

如果在这一行代码执行之前已经添加了引用这个文件,那么请将 Include 修改为 Update 请看下面代码

    <ItemGroup>
    	<None Include="*.txt"/>
    	<!-- 上面的代码使用 *.txt 包含了 林德熙是逗比.txt 文件,需要在下面代码使用更新 -->
        <None Update="林德熙是逗比.txt"
              Pack="True"
              PackagePath="\lib\doubi\" />	
    </ItemGroup>

而如果是引用了输出文件里面的某个 dll 如我引用了 Newtonsoft.Json.dll 这个库文件,我需要在 bin\release 文件夹里面引用文件,那么我将需要这样写

        <ItemGroup>
            <None Include="$(OutputPath)\net48\Newtonsoft.Json.dll"
                  Pack="True"
                  PackagePath="\tools\net48\Newtonsoft.Json.dll" />
        </ItemGroup>

上面代码将会在输出文件夹找到 Newtonsoft.Json.dll 将这个文件输出到打包文件夹里面

如果我是需要在运行过程引用的一些 C++ 运行库,那么同样可以上面方法

另外在输出的时候也支持改名,例如在写 NuGet 的时候,在修改编译过程的 targets 和 props 文件是需要跟随包的名才能被执行。例如在 Roslyn 通过 Target 修改编译的文件 写到的替换编译文件,此时要求对应的文件有规定的命名

在 NuGet 里面,要求执行的 targets 文件必须满足命名要求,需要命名为 NuGet包id.targets 才会被执行,对应的 props 文件也相同

如果是自己手写文件名,在更改 NuGet 包 id 的时候如果没有更改,或复制不对,那么会发现没有执行

简单的解决方法是在打包的时候自动修改对应的文件包

先在项目文件的 build 文件夹里面添加 package.targets 和 package.props 文件,在项目文件添加下面代码进行输出

<None Include="build\package.targets" Pack="True" PackagePath="\build\$(PackageId).targets" />
<None Include="build\package.props" Pack="True" PackagePath="\build\$(PackageId).props" />

这样在输出的时候就会自动更改文件名

在 package.targets 文件让对应的放在 NuGet 文件的资源输出,通过 Copy 的方式输出

先定义一个 Target 可以在编译完成之后输出

<Project>
    <Target Name="CopyXxxFile" AfterTargets="AfterBuild">

    </Target>
</Project>

请将 Target 的名修改为实际使用的复制文件

    <Target Name="_CopyXxxFile" AfterTargets="AfterBuild">
        <Copy SourceFiles="$(MSBuildThisFileDirectory)..\tools\nuget.exe" DestinationFiles="$(OutputPath)\tools\nuget.exe" SkipUnchangedFiles="True"></Copy>
    </Target>

使用 $(MSBuildThisFileDirectory) 拿到当前文件的文件夹,此时通过上一层文件就可以拿到 NuGet 包的文件夹。获取对应的文件进行输出到软件编译输出文件夹

关于文件复制请看 Roslyn 如何使用 MSBuild Copy 复制文件

如果这个库文件只是需要添加资源文件,不需要加上 lib 文件,也就是不添加引用,那么请设置这个项目作为工具库

    <IsTool>true</IsTool>
    <NoPackageAnalysis>true</NoPackageAnalysis>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <NoBuild>true</NoBuild>
    <IncludeBuildOutput>false</IncludeBuildOutput>

通过 IsTool 将不会在安装的项目引用编译的文件,也就是这个 NuGet 库只是工具,里面的 dll 不会被引用

在 NuGet 包嵌入 符号文件 的方法是添加 AllowedOutputExtensionsInPackageBuildOutputFolder 属性

<Project Sdk="Microsoft.NET.Sdk">
 <PropertyGroup>
    <!-- Include symbol files (*.pdb) in the built .nupkg -->
    <AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
  </PropertyGroup>
</Project>

默认符号文件是放在 snupkg 文件,而不是放在 nupkg 文件,原因是将符号文件放在 nupkg 文件,会让 nupkg 文件太大。如果将符号文件放在 nupkg 文件,那么不需要开发者另外配置符号服务器,就可以拿到符号文件

官方文档 NuGet 和 .NET 库 里明确告诉小伙伴请考虑将符号作为符号包 (*.snupkg) 发布到 NuGet.org 而不是放在 nupkg 文件,符号包 (*.snupkg) 为开发人员提供了良好的按需调试体验,而不会使主程序包大小膨胀,也不会影响那些不打算调试 NuGet 包的用户的还原性能

如果只是需要放注释文档,请看 Roslyn 在 NuGet 包中放注释 xml 文件的方法

详细请看 NuGet 命令行上传找不到 snupkg 文件

Roslyn 使用 Target 替换占位符方式生成 nuget 打包

如何编写基于 Microsoft.NET.Sdk 的跨平台的 MSBuild Target(附各种自带的 Task) - walterlv

如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包 - walterlv

Roslyn 如何在 Target 引用 xaml 防止文件没有编译

Roslyn 通过 Target 修改编译的文件

lindexi%2F20197917354626


本文会经常更新,请阅读原文: https://blog.lindexi.com/post/Roslyn-%E6%89%93%E5%8C%85%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84%E6%96%87%E4%BB%B6%E5%88%B0-NuGet-%E5%8C%85.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者前往 CSDN 关注我的主页

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

无盈利,不卖课,做纯粹的技术博客

以下是广告时间

推荐关注 Edi.Wang 的公众号
lindexi%2F201985113622445

欢迎进入 Eleven 老师组建的 .NET 社区
lindexi%2F20209121930471745.jpg

以上广告全是友情推广,无盈利


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK