我为 Universal Windows 开发了一个基于C / C ++的 Windows运行时组件,我现在正试图将其包含在NuGet广告中。
使用NuGet版本3时,已引入运行时文件夹,有关详细信息,请参阅here。不幸的是,本文档没有提供有关如何处理 Windows运行时组件的更多信息。
我已经在NuGet包中组织了这样的文件:
└───MyNuGetPackage
├───lib
│ └───uap
│ MyRuntimeLibrary.winmd
│
├───build
│ └───uap
│ MyNuGetPackage.targets
│
└───runtimes
├───win10-x86
│ └───native
│ MyRuntimeLibrary.dll
│
├───win10-x64
│ └───native
│ MyRuntimeLibrary.dll
│
└───win10-arm
└───native
MyRuntimeLibrary.dll
MyNuGetPackage.targets 文件在构建过程中用于添加对 .winmd 文件的引用,并明确指定实现 .dll :
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="InjectReference" BeforeTargets="ResolveAssemblyReferences">
<ItemGroup Condition=" '$(Platform)' == 'x86' or '$(Platform)' == 'x64' or '$(Platform)' == 'ARM'">
<Reference Include="Dicom.Imaging.Codec">
<HintPath>$(MSBuildThisFileDirectory)..\..\lib\uap\MyRuntimeLibrary.winmd</HintPath>
<Implementation>MyRuntimeLibrary.dll</Implementation>
</Reference>
</ItemGroup>
</Target>
</Project>
据我所知,这个NuGet包组合有效;构建不同平台 x86 , x64 和 ARM 时,会选择相关的实施文件。
但是,通过上述方法,我只包含来自一个目标平台的 .winmd 文件(在此特定情况下为 x86 )。 这真的好吗?它似乎有用,但实际上 .winmd 文件平台是独立的吗?
如果 .winmd 文件是平台依赖,我试图在下添加特定于平台目标的 .winmd 文件运行时文件夹,如下所示:
└───runtimes
├───win10-x86
│ └───lib
│ └───uap
│ MyRuntimeLibrary.winmd
│ └───native
│ MyRuntimeLibrary.dll
我已相应更新 MyNuGetPackage.targets 文件。但是,当我安装这个替代的NuGet包并尝试为特定平台构建时,我得到一个有效负载构建错误, MyRuntimeLibrary.winmd 文件正从两个不同的位置复制到输出目录, lib \ uap 文件夹和运行时子文件夹。
完全排除顶部 lib \ uap 文件夹也无济于事;如果我这样做,构建过程根本找不到任何 .winmd 文件引用。
如果 .winmd 文件毕竟是依赖于平台的,我该如何组织NuGet包中的 .winmd 和 .dll 文件确保软件包在所有平台上安装充分?
答案 0 :(得分:4)
理解.winmd文件的真正含义可能会有所帮助。它是旧的COM类型库的重新构造,您可能之前遇到过.tlb文件。可能之前使用OleView.exe SDK实用程序File + View Typelib命令查看了其内容。
与.NET元数据大致相同,您的个人资料显示您之前肯定使用过它们。您在C#项目的References节点中找到的文件。您可能以前使用ildasm.exe或.NET反编译器(如Reflector或ILSpy)查看过它们。或IDE的Go To Declaration命令。您已经知道此类引用与平台无关。
Microsoft退出.tlb文件格式并将其替换为.NET元数据文件格式。一种足够灵活的格式,也可以表达COM声明。并且可扩展到足以表达WinRT声明,这种声明无法被打成.tlb格式。像泛型和属性一样,语言投影大量使用,使COM客户端代码更容易编写。非常好的举措,微软必须做很少的工作来改变现有的工具,比如C#编译器,才能使用.winmd文件。
长话短说,它在编译时就像.NET程序集和COM类型库一样。编译器使用它来检索类型声明。您可以使其平台依赖于平台,例如在您打算使用int
时使用IntPtr
。但是你用你编程的任何语言使用的语言投影都是非常罕见的事故。当你测试时很快发现。