我可以将引用dll放在C#的特定目录中吗?

时间:2012-08-30 09:02:28

标签: c# dll reference 32bit-64bit

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

我在解决方案中有5个项目如下:

  • IHCommon(班级图书馆)
    • 参考
      • IHLib64(作为项目)
      • IHLib32(作为项目)
  • IHLib64(类库)
    • 参考
      • aLibrary.dll(为64位计算机编译的第三方dll)
  • IHLib32(类库)
    • 参考
      • aLibrary.dll(为32位计算机编译的第三方dll)
  • IHWebUtility(类库)
    • 参考
      • IHCommon(作为项目)
  • WebSite(Web项目)
    • 参考
      • IHWebUtility(作为项目)

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

工作正常。

问题出在WebSite的bin文件夹中,32位版本的“aLibrary.dll”正试图找到64位版本的“aLibrary.dll”想要找到的位置。

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

如何将它们分隔到bin \ x86和bin \ x64等单独的文件夹中?

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

我试图修复.csproj文件,但它确实无法解决。

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

代码太大了。

[编辑]致丹尼尔

您的意思是,我必须按照以下方式修复这些项目:

  • IHCommon(班级图书馆)
    • DLL
      • 86
        • aLibrary.dll(为32位计算机编译的第三方dll)
      • 64
        • aLibrary.dll(为64位计算机编译的第三方dll)
  • IHWebUtility(类库)
    • 参考
      • IHCommon(作为项目)
  • WebSite(Web项目)
    • 参考
      • IHWebUtility(作为项目)

1 个答案:

答案 0 :(得分: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;
}

在应用程序的最开始部分执行此代码非常重要。