强制app忽略本地程序集并使用SxS,反之亦然

时间:2014-10-07 14:55:09

标签: c# .net dll manifest winsxs

我有一个部署在两种版本中的应用程序,管理员亲自使用WiX安装程序,或者没有提升权限的用户使用单击一次安装程序。它依赖于一组第三方dll,这些dll旨在以SxS方式部署。但是,由于需要提升安装到winSxS的权限,因此单击一次安装需要将文件本地安装到应用程序的bin目录中。这在WiX安装中也是可能的,并且没有问题,但是存在问题......

使用同一组dll的其他第三方(或第四方)应用程序将它们安装到winSxS中,当我们的应用程序加载时,它访问winSxS中的本地版本和版本。对于SxS dll从非托管资源dll加载的资源,这会导致一些奇怪的UI损坏。

使第三方共享SxS集中的所有dll都嵌入了一个清单,直接指定了对SxS集的依赖。

我尝试在应用程序清单中添加对SxS集的依赖性,但问题仍然存在,即访问了两个版本:

<dependency>
    <dependentAssembly>
        <assemblyIdentity name="sharedSXS" version="12.1.369.0" publicKeyToken="1255b113b2b03444" type="win32"/>
    </dependentAssembly>
</dependency>

但是无济于事。

我的问题是:

如果计算机上没有安装其他应用程序并且dll位于应用程序bin目录中,有没有办法继续成功运行应用程序,同时如果另一个应用程序将dll安装到winSxS中,则还可以成功运行。 换句话说,我是否可以强制应用程序仅从winSxS或本地加载,而这两种情况都存在于winSxS中存在dll的情况中。

额外信息

应用程序使用dllImport:

访问dll
[DllImport("ExternalDll.dll", EntryPoint = "_DoStuff@12")]
[CLSCompliantAttribute(false)]
public static extern IntPtr DoStuffEx(string name, string reserved, uint uiFlags);

并且dll具有嵌入式清单:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity name="ExternalDLL.dll" processorArchitecture="x86" type="win32" version="12.0.0.0"></assemblyIdentity>
 <dependency>
    <dependentAssembly>
        <assemblyIdentity name="sharedSXS" version="12.1.369.0" publicKeyToken="1255b113b2b03444" type="win32"/>
    </dependentAssembly>
</dependency>
</assembly>

和SxS Manifest如下所示:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="sharedSXS" version="12.1.369.0" publicKeyToken="1255b113b2b03444"></assemblyIdentity>
<file name="ExternalDLL.dll" hashalg="SHA1" hash="cb2ecfaca2d62cd9f5c559cf21d502921881155f"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>BLyJ40vJD++ih9XTg0oOcZhISl4=</dsig:DigestValue></asmv2:hash></file>
<file name="OtherDLL.dll" hashalg="SHA1" hash="246d082823724f42d5630dba1b9dcde3e2c1b76d"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>me1EL8p76nkfD1o9L058m8GUdaw=</dsig:DigestValue></asmv2:hash></file>
</assembly>

有4种情况:

  1. 应用程序没有清单,未安装SxS - &gt;应用程序在本地加载DLL,如果存在其他失败
  2. 应用程序已显示,未安装SxS - &gt;应用程序在本地加载DLL,如果存在其他失败
  3. 应用程序没有清单,SxS存在 - &gt;

    一个。应用程序在本地加载DLL,如果存在,则dll然后从SxS损坏发生加载依赖

    B中。没有本地DLL,应用程序失败

  4. 应用程序有清单,SxS存在 - &gt;

    一个。应用程序在本地加载DLL,如果存在,则dll然后从SxS损坏发生加载依赖

    B中。没有本地dll,来自SxS的app加载都很好

  5. 我需要做两种工作:

    1. 仅限本地文件夹中的dll(SxS中没有)
    2. 本地文件夹中的dll和SxS
    3. 我可以完全控制应用程序清单和dllImport,因此这里需要的任何修改都在我的控制之下。仅在SxS中使用dll的场景是无关紧要的。

1 个答案:

答案 0 :(得分:0)

如何安装本地程序集?您是否尝试在程序集名称文件夹中安装它们?

yourapp.exe
sharedSXS/ExternalDLL.dll
sharedSXS/sharedSXS.manifest
sharedSXS/OtherDLL.dll

然后没有清单的应用程序根本找不到dll,带有清单的应用程序在本地复制之前更喜欢全局复制,从不使用这两者。