2

32ビットコンピューターで作業していますが、64ビットサーバーに展開しています。

私は以下のようなソリューションで5つのプロジェクトを持っています:

  • IHCommon(クラスライブラリ)
    • 参照
      • IHLib64(プロジェクトとして)
      • IHLib32(プロジェクトとして)
  • IHLib64(クラスライブラリ)
    • 参照
      • aLibrary.dll(64ビットコンピューター用にコンパイルされたサードパーティのdll)
  • IHLib32(クラスライブラリ)
    • 参照
      • aLibrary.dll(32ビットコンピューター用にコンパイルされたサードパーティのdll)
  • IHWebUtility(クラスライブラリ)
    • 参照
      • IHCommon(プロジェクトとして)
  • Webサイト(Webプロジェクト)
    • 参照
      • IHWebUtility(プロジェクトとして)

これが私のポイントです。私のWebサイトアプリケーションは「aLibrary.dll」で記述された関数を実行する必要があるため、CPUタイプの条件で「IHCommon」プロジェクトから「IHLib64」または「IHLib32」を呼び出すことができました。

正常に動作します。

問題はWebサイトのbinフォルダーにあり、32ビットバージョンの「aLibrary.dll」が64ビットバージョンの「aLibrary.dll」が検索しようとしているため、検索しようとしています。

それらは同じ名前を持っているので、同じフォルダにとどまることができません。

それらをbin\x86やbin\x64などの個別のフォルダーに分割するにはどうすればよいですか?

私の本当の大きなポイントは、それらを私のソリューションに含めることですが、CPUタイプの条件でそれらを実行します。

.csprojファイルを修正しようとしましたが、うまくいきませんでした。

[編集].NETReflectionも使おうとしましたが、以前のコードには適用できません。

コードが大きすぎます。

[編集]ダニエルに

つまり、これらのプロジェクトを次のように修正する必要があります。

  • IHCommon(クラスライブラリ)
    • DLL
      • x86
        • aLibrary.dll(32ビットコンピューター用にコンパイルされたサードパーティのdll)
      • x64
        • aLibrary.dll(64ビットコンピューター用にコンパイルされたサードパーティのdll)
  • IHWebUtility(クラスライブラリ)
    • 参照
      • IHCommon(プロジェクトとして)
  • Webサイト(Webプロジェクト)
    • 参照
      • IHWebUtility(プロジェクトとして)
4

1 に答える 1

3

私のプロジェクトの1つで、同様の問題が発生しました。

x86およびx64マシンで変更なしで実行できる1つの展開パッケージが必要でした。また、1つのCPUタイプ用にコンパイルされたサードパーティのDLLを利用しました。サードパーティのDLLを管理および管理していませんでした。
x86のDLLはx86という名前のサブフォルダーにあり、x64のDLLはx64という名前のサブフォルダーにありました。

アンマネージDLLのアプローチは、コードが実際に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 に答える