.winmd文件平台是独立的吗?

时间:2015-11-03 09:47:56

标签: windows-runtime nuget win-universal-app

我为 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 文件确保软件包在所有平台上安装充分?

1 个答案:

答案 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。但是你用你编程的任何语言使用的语言投影都是非常罕见的事故。当你测试时很快发现。