2

我正在使用 32 位计算机,但部署到 64 位服务器。

我在一个解决方案中有 5 个项目,如下所示:

  • IHCommon(类库)
    • 参考
      • IHLib64(作为项目)
      • IHLib32(作为项目)
  • IHLib64(类库)
    • 参考
      • aLibrary.dll(为 64 位计算机编译的第三方 dll)
  • IHLib32(类库)
    • 参考
      • aLibrary.dll(为 32 位计算机编译的第三方 dll)
  • IHWebUtility(类库)
    • 参考
      • IHCommon(作为一个项目)
  • 网站(网络项目)
    • 参考
      • IHWebUtility(作为一个项目)

这是我的观点。我的网站应用程序必须运行一些用“aLibrary.dll”编写的函数,所以我设法在 CPU 类型的情况下从“IHCommon”项目中调用“IHLib64”或“IHLib32”。

它工作正常。

问题出在网站的 bin 文件夹中,32 位版本的“aLibrary.dll”正在尝试定位,而 64 位版本的“aLibrary.dll”想要定位。

它们具有相同的名称,因此它们不能留在同一个文件夹中。

如何将它们分成单独的文件夹,如 bin\x86 和 bin\x64?

我真正的重点是将它们包含在我的解决方案中,但在 CPU 类型的条件下运行它们。

我试图修复 .csproj 文件,但没有成功。

[编辑] 我也尝试过使用 .NET Reflection,但我真的不能将它应用到我以前的代码中。

代码转换太大。

[编辑]致丹尼尔

你的意思是,我必须按如下方式修复这些项目:

  • IHCommon(类库)
    • 动态链接库
      • x86
        • aLibrary.dll(为 32 位计算机编译的第三方 dll)
      • x64
        • aLibrary.dll(为 64 位计算机编译的第三方 dll)
  • IHWebUtility(类库)
    • 参考
      • IHCommon(作为一个项目)
  • 网站(网络项目)
    • 参考
      • IHWebUtility(作为一个项目)
4

1 回答 1

3

在我的一个项目中,我遇到了类似的问题:

我想要一个可以在 x86 和 x64 机器上运行而无需任何更改的部署包。它还利用了为一种 CPU 类型编译的第三方 DLL。我有托管和非托管的第三方 DLL。
x86 的 DLL 位于名为 x86 的子文件夹中,而 x64 的 DLL 位于名为 x64 的子文件夹中。

非托管 DLL 的方法是在代码真正需要它们之前预加载它们。通过这种方法,我可以决定要加载哪个版本:

[DllImport("Kernel32.dll")]
private static extern IntPtr LoadLibrary(string path);

void LoadLibraryIfExists(string path)
{
    if (File.Exists(path))
        LoadLibrary(path);
}

var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetCallingAssembly();
var path = Path.GetDirectoryName(assembly.Location);
path = Path.Combine(path, Environment.Is64BitProcess ? "x64" : "x86", "unmanaged.dll");

LoadLibraryIfExists(path);

稍后执行并需要相同非托管 DLL 的任何代码都使用上面代码加载的版本。

对于托管程序集,您必须挂钩AssemblyResolve事件并自己解决程序集。就像以前一样,您现在可以决定加载哪一个。
已使用以下代码:

AppDomain.CurrentDomain.AssemblyResolve += 
    (s, e) => OnAssemblyResolve(Environment.Is64BitProcess, e.Name);

private Assembly LoadAssemblyIfExists(string path)
{
    if (!File.Exists(path))
        return null;
    return Assembly.LoadFrom(path);
}

private Assembly OnAssemblyResolve(bool is64BitProcess, string assemblyDisplayName)
{
    try
    {
        var assemblyName = new AssemblyName(assemblyDisplayName);

        if (assemblyName.Name == "Managed")
        {
            var assembly = Assembly.GetEntryAssembly() ?? 
                           Assembly.GetCallingAssembly();
            var path = Path.GetDirectoryName(assembly.Location);
            path = Path.Combine(path, is64BitProcess ? "x64" : "x86", "Managed.dll"); 

            return LoadAssemblyIfExists(path);
        }
    }
    catch (Exception e)
    {
        var message = string.Format(
            "Error resolving assembly {0}. Falling back to default resolve behavior", 
            assemblyDisplayName);
        Logger.WarnException(message, e);
    }

    return null;
}

在应用程序的最开始执行此代码很重要。

于 2012-08-30T09:09:04.160 回答