Nuget 是 dotnet 開發中必不可少的包管理工具,但不單單侷限於 dotnet 項目,在 VS 中使用 C++ 開發的時候,也可使用 Nuget 來引用第三方組件。一樣也能夠用 Nuget 把 native 的一些組件打包,提供給本身或者別人使用。windows
這片博文記錄一下如何把 WinRT 組件打包成 nuget 包,供 UWP 項目使用。服務器
以前提供給合做夥伴咱們的 WinRT 組件時,是直接把 .winmd文件 和 .dll文件發給他們,其中 .winmd 提供聲明,.dll 提供具體的實現。而後使用者就能夠手動引用和複製這兩個文件到項目裏面使用。架構
主要包含命名空間,類之類的聲明,由於本質上使用的是 COM 技術,因此即便只添加對 .winmd 的引用,UWP 項目依舊能夠成功編譯。app
包含對應 .winmd 的具體 COM 實現。ide
用來打包 nuget 包,能夠從 nuget 官網下載(https://www.nuget.org/downloads )工具
可使用以下命令來生成一個名爲 demo.nuspec 的模板文件ui
nuget spec demo
在此文件中,須要加入對 Demo.winmd 和 Demo.dll 文件的引用,修改完成後以下this
<?xml version="1.0"?> <package > <metadata> <id>com.cq.nugetdemo</id> <version>1.0.0.0</version> <title>Nuget Demo</title> <authors>cq</authors> <owners>cq</owners> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>Just a test</description> <releaseNotes>Summary of changes made in this release of the package.</releaseNotes> <copyright>Copyright 2019</copyright> <tags>demo</tags> </metadata> <files> <!-- WinMd and IntelliSense files --> <file src=".\Nuget.winmd" target="lib\uap10.0"/> <!-- DLLs and resources --> <file src=".\Nuget.dll" target="runtimes\win10-x64\native"/> <!-- .targets --> <file src="com.cq.nugetdemo.targets" target="build\native"/> </files> </package>
metadata 節點提供一些必要的 nuget 包信息聲明,最重要的是 id,這個要保證惟一性。code
引用文件的位置是以 demo.nuspec 文件的位置爲基準,可使用相對路徑。orm
須要將 nuget.winmd 文件放入 lib 文件夾下的 uap10.0 目錄,其中 lib 文件夾會在最終生成的 nuget 包中建立,uap10.0 表明此文件只會被 UWP 應用引用。
須要將 demo.dll 文件放入 runtimes 文件夾下,一樣這個文件夾咱們不須要手動建立,它會在最終生成的 nuget 包中出現。win10-x64 表明該 dll 爲 x64 cpu 架構,win10-x86 就表明32位,native 則表示此 dll的類型。
com.cq.nugetdemo.targets 文件和 demo.nuspec 文件在同一目錄,它主要是爲了讓 C++ 的 UWP 項目也能正確添加對 nuget 包中 dll 和 winmd 文件的引用,在 C# 項目裏面IDE會幫咱們添加。 該文件以下:
<?xml version="1.0" encoding="utf-8"?> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <NugetDemo-Platform Condition="'$(Platform)' == 'Win32'">x86</NugetDemo-Platform> <NugetDemo-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</NugetDemo-Platform> </PropertyGroup> <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'UAP'"> <Reference Include="$(MSBuildThisFileDirectory)..\..\lib\uap10.0\Nuget.winmd"> <Implementation>Demo.dll</Implementation> </Reference> <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-$(NugetDemo-Platform)\native\Demo.dll" /> </ItemGroup> </Project>
雖然 C# 的 UWP 項目不須要 .targets 文件,可是爲了讓 IDE 能正確添加對 DLL 文件的引用,咱們須要保持 dll 和 winmd 文件同名,不然在運行時會拋出異常。在編譯時,會有以下警告:
warning APPX1707: No implementation file was provided for the .winmd file 'C:\Users\...\.nuget\packages\com.cq.nugetdemo\1.0.0.3\lib\uap10.0\demo.winmd'. To generate registration information in the app manifest, specify the 'Implementation' metadata on the .winmd reference item in the project file.
nuget.exe pack NugetDemo.nuspec -Version 1.0.0.3
在建立的時候,能夠指定版本號,這方便咱們用自動化腳原本生成 nuget 包。執行此命令後,在demo.nuspec 同級目錄下會生成對應的 .nupkg。
正常使用 nuget 包時,能夠經過 VS 裏的 nuget 包管理器去安裝。可是若是咱們的 nuget 包只想本地使用,那咱們能夠給 nuget 包管理器添加一個本地的包源,
在 .sln 同級目錄,建立一個 Nuget.config 文件,而後能夠在裏面配置本地的 nuget source
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="MyLocalSource" value=".\NugetPackage" /> </packageSources> </configuration>
其中 MyLocalSource 是包源的名稱,.\NugetPackage 是包源的路徑,也是相對路徑
如今就能夠在包管理器中選擇對應的本地源,而後安裝生成的 .nupkg
我主要參考了微軟的官方文檔:
https://docs.microsoft.com/en-us/nuget/guides/create-uwp-packages
微軟文檔會更加全面一些,而這篇博客主要是個人具體實踐,對比該文檔去掉了一些 暫時沒發現有什麼用 的步驟,添加了一些值得注意的點。
事實上在 demo.dll 是一個 COM 服務器,使用前須要先註冊,在 UWP 項目裏如何註冊這個 COM 服務器呢?
當咱們添加對 .winmd 和 .dll 的引用後,在 UWP 的 AppMenifest 文件裏面會自動添加以下節點:
<Package> <Extensions> <Extension Category="windows.activatableClass.inProcessServer"> <InProcessServer> <Path>Nuget.dll</Path> <ActivatableClass ActivatableClassId="Nuget.Class" ThreadingModel="both" /> </InProcessServer> </Extension> </Extensions> </Package>