1

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

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

使事情复杂化的是,来自第 3 方的共享 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 加载或在本地加载,无论是否存在 dll 都存在于 winSxS 中。

额外信息

应用程序使用 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 清单如下所示:

<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 -> 应用程序在本地加载 dll(如果存在),否则失败
  2. 应用程序有清单,未安装 SxS -> 应用程序在本地加载 dll,如果存在,否则失败
  3. 应用程序没有清单,存在 SxS ->

    A. 应用程序在本地加载 dll(如果存在),然后 dll 加载来自 SxS 损坏的依赖项

    B.没有本地dll,app失败

  4. 应用程序有清单,存在 SxS ->

    A. 应用程序在本地加载 dll(如果存在),然后 dll 加载来自 SxS 损坏的依赖项

    B. 没有本地 dll,从 SxS 加载应用程序一切正常

我需要做两个场景:

  1. dll 仅在本地文件夹中(在 SxS 中没有)
  2. 本地文件夹和 SxS 中的 dll

我可以完全控制应用程序清单和 dllImport,因此此处需要的任何修改都在我的控制之下。仅在 SxS 中使用 dll 的情况无关紧要。

4

1 回答 1

0

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

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

然后没有清单的应用程序将根本找不到 dll,具有清单的应用程序将优先选择全局副本而不是本地副本,从不同时使用两者。

于 2014-10-15T15:50:09.600 回答