VS打包之 MSBuild Community Tasks 使用介紹
本文重點介紹Windows下,在不調用外部工具的前提下,對目标檔案和相關的資源檔案進行打包。
Windows雞肋的指令行使得 VS 建構後的打包釋出很是頭疼,最簡單的打包也沒有内建指令,更沒類似于 Java 下 Maven 的助攻。唯一找到的 .NET MAVEN PLUGIN 還需要依賴 dotnet core 這個外援,慘呐慘!
如果需要在 build 完成後做一些打包之類的處理,一種方式是在 VS 的 post-build 中編寫腳本,另外一種方式是使用 MSBuild Community Tasks 這個 Nuget 包,Github 位址:https://github.com/loresoft/msbuildtasks。MSBuild Community Tasks是一個開源的封裝了MSBuild Task的庫,支援諸如FTP上傳,發送郵件,移動檔案,運作NUnit測試,Svn操作,Zip壓縮及解壓縮等,詳細支援的Task詳見官方文檔:Community Tasks 。
Zip 打包
目前目錄結構如下:
| Hello.csproj
| packages.config
| Hello.sln
├─bin
│ ├─Debug
│ └─Release
├─obj
├─packages
│ └─MSBuildTasks
│ │ MSBuildTasks.nupkg
│ │
│ ├─build
│ │ MSBuildTasks.targets
│ │
│ └─tools
│ MSBuild.Community.Tasks.dll
│ MSBuild.Community.Tasks.Targets
│ MSBuild.Community.Tasks.xml
│ MSBuild.Community.Tasks.xsd
│
├─scripts
│ │ Web.config
│ ├─includes
│ │ advanced.html
│ ├─src
│ │ createTestFiles.txt
│ ├─testfiles
│ │ image.png
│ └─ui
│ ├─images
│ │ icon.png
│ └─js
│ jquery.js
└─src
HellowWord.cs
安裝 MSBuild Community Tasks
安裝方式參考官方文檔。安裝完 MSBuild Community Tasks 之後,packages.config 中會多出一條配置資訊:
<package id="MSBuildTasks" version="1.5.0.235" targetFramework="net461" developmentDependency="true" />
同時 Hello.csproj 會增加如下資訊:
<Import Project="packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.targets" Condition="Exists('packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\MSBuildTasks.1.5.0.235\build\MSBuildTasks.targets'))" />
</Target>
在上述配置後面追加打包的配置,例如:
<!-- Release模式下建構成功後後執行 -->
<Target Name="AfterBuild" Condition="'$(Configuration)'=='Release'">
<ItemGroup>
<!-- ZipFiles 需要打包的檔案,可以定義多個 ZipFiles -->
<ZipFiles Include="kits\$(ProjectName)" />
<!-- 定義一個ItemGroup友善後續拷貝。 **\*.*: 遞歸拷貝目錄下所有的檔案 -->
<ScriptFiles Include="scripts\**\*.*" />
</ItemGroup>
<!-- 删除(清空)臨時目錄,RemoveDir是VS的一個Task -->
<RemoveDir Directories="@(ZipFiles)" />
<!-- 将scripts下的所有檔案拷貝到 kits\$(ProjectName) 目錄下,并保持目錄結構。 -->
<!-- %(RecursiveDir)%(Filename)%(Extension):拷貝檔案時保持其目錄結構 -->
<!-- 如果不需要保持目錄結構,隻拷貝檔案,将 DestinationFiles 替換成 DestinationFolder。-->
<Copy SourceFiles="@(ScriptFiles)" DestinationFiles="@(ScriptFiles->'kits\$(ProjectName)\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="$(TargetPath)" DestinationFolder="kits\$(ProjectName)\lib" />
<!-- 調用 Zip task 進行打包 -->
<!-- Flatten="True",隻打封包件,不保留目錄結構-->
<!-- Flatten="False" 保留目錄結構,目錄是以 WorkingDirectory 為相對目錄 -->
<Zip ZipFileName="kits\$(ProjectName).zip" WorkingDirectory="kits" Files="@(ZipFiles)" Flatten="False" Quiet="true" />
<RemoveDir Directories="@(ZipFiles)" />
</Target>
在 Release 模式下建構成功後,将生成的目标檔案和scripts目錄下的所有檔案打包到 kits/Hello.zip 檔案中,并保持目錄結構,zip中檔案結構
Hello
| Web.config
├─lib
│ Hello.dll
├─includes
│ advanced.html
├─src
│ createTestFiles.txt
├─testfiles
│ image.png
└─ui
├─images
│ icon.png
└─js
jquery.js
Reference
Zip 參考:
- 官方Zip示例
- Zip其他參數及含義 - 參考代碼注釋
Task參考:
- RemoveDir Task 文檔
- Copy Task 文檔
- 所有可用Task浏覽
Other Example:
techstay/MSBuildExample