【问题标题】:Portable Class Library strong assembly reference problems in MonoTouch/MonoDroidMonoTouch/MonoDroid 中可移植类库强汇编参考问题
【发布时间】:2012-10-23 10:21:46
【问题描述】:

PCL 在 MonoTouch 和 MonoDroid 中运行良好。

但是,有时,当我使用变量引用 PCL 中的类型,然后尝试在 MonoX 客户端中使用相同的引用时,编译器会失败并显示如下消息:

“System.Collections.Specialized.INotifyCollectionChanged”类型在未引用的程序集中定义。您必须添加对程序集 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes' 的引用。

这里的问题是,在 MonoDroid 中,我的 System.Collections.Specialized.INotifyCollectionChanged PCL 在 shim 类型转发 DLL 中提供 - 例如 https://github.com/slodge/MvvmCross/tree/vnext/Cirrious/System.Windows - 显然无法使用 Microsoft 的私钥对 DLL 进行签名。

更多信息:

  • 这在 ICommand 和 INotifyCollectionChanged 等接口中很常见
  • 它似乎只发生在 .exe 项目中(库以某种方式工作正常)
  • 我主要在 VS2010 和 VS2012 中测试/构建
  • 更多信息:https://github.com/slodge/MvvmCross/issues/41

任何人都可以提出任何解决此问题的方法吗?例如有没有办法关闭强大的程序集命名保护?

我认为如果 PCL 要在 Microsoft 发布的 .Net 实现之外真正可移植,我认为这是必要的?

【问题讨论】:

    标签: xamarin.ios xamarin.android portable-class-library


    【解决方案1】:

    从管理员 VS 命令提示符中,您可以运行以下命令:

    sn -Vr *,7cec85d7bea7798e
    

    这将跳过以 7cec85d7bea7798e 作为公钥令牌的任何程序集的强名称验证。然后您应该能够延迟使用该密钥对您的 shim DLL 进行签名。我认为您可以使用sn -pc 从 DLL 中提取密钥的公共部分,以便将其用于延迟签名。

    这应该允许您使用垫片进行编译。当然,它也需要在运行时工作。我认为 MonoTouch 和 MonoDroid 实际上并没有验证程序集的强名称键,所以它会正常工作。如果他们确实进行了此验证,那么我认为您无能为力。在这种情况下,要么 Mono 需要进行一些更改以支持这些类型引用或忽略 shim 的密钥,要么 Microsoft 需要提供您可以使用的 shim DLL 的签名版本。

    请注意,我不是安全专家,因此我不知道在您的计算机上禁用这些 Microsoft 密钥的强名称验证可能会产生什么样的安全影响。我不认为会有任何重大影响...


    Daniel 的详细跟进:

    我认为这是解决 Mono 上可移植库的类型共享/强名称签名问题所需要做的:

    -> 提取System.Windows.dll的公钥,放到Droid System.Windows项目的项目目录下:

     Sn –e "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\Profile104\System.Windows.dll" system_windows.snk
    

    -> 修改 Droid system.windows 项目以使用提取的密钥进行延迟签名。将以下内容放在 csproj 文件的 PropertyGroup 中:

    <SignAssembly>true</SignAssembly>
    <AssemblyOriginatorKeyFile>system_windows.snk</AssemblyOriginatorKeyFile>
    <DelaySign>true</DelaySign>
    

    -> 将 Droid System.Windows 项目(在 AssemblyInfo.cs 中)的程序集版本更改为:

    2.0.5.0 
    

    在我的测试中,我似乎不需要禁用强名称验证。所以我认为它不会给新手带来任何额外的障碍——一旦你做了这些改变,他们只需要获取你的代码,它就会正确构建。

    但是,如果您确实遇到问题,请尝试从管理员 VS 命令提示符运行以下命令:

     sn -Vr *,7cec85d7bea7798e 
    

    让我知道这是如何工作的!

    谢谢,

    丹尼尔

    【讨论】:

    • 谢谢。我一直在运行代码 - 所以你关于缺乏运行时验证的断言似乎是正确的。我必须仔细完成您答案中的步骤才能理解它们。我从来没有做过任何代码签名,所以你的很多指令对我来说听起来像是一门外语 :) 在我有一些工作后会回来提供更多反馈。
    【解决方案2】:

    我的项目中有类似的问题,当我尝试构建 MonoDroid 或 MonoTouch 项目时,我的 PCL 用于 .Net 4.5、Windows Phone 8、WinRT、MonoTouch 和 MonoDroid,错误如下:

    *错误 1 ​​类型“System.Object”在未引用的程序集中定义。您必须添加对程序集“System.Runtime”的引用, 版本=4.0.0.0,文化=中性,PublicKeyToken=b03f5f7f11d50a3a'。

    错误 2 类型 'System.Enum' 是在一个未定义的程序集中定义的 参考。您必须添加对程序集“System.Runtime”的引用, 版本=4.0.0.0,文化=中性,PublicKeyToken=b03f5f7f11d50a3a'。

    我已经完成了建议的命令 (sn -Vr *,b03f5f7f11d50a3a),但没有帮助。 我正在使用以下配置文件:

    C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile78
    

    【讨论】:

    • 您需要将其作为一个真正引用此问题的新问题提出。有人可能会帮助你(@dsplaisted 最终帮助了我!)
    猜你喜欢
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    相关资源
    最近更新 更多