3

アセンブリ解決に関する私の最後の質問 ( AppDomain.CurrentDomain.AssemblyResolve が <AppName>.resources アセンブリを要求していますか? ) の答えを見つけた後、参照アセンブリを自分のプログラムに埋め込むことができるようになりました。

まず、Program.cs の最初の入り口でアセンブリ リゾルバーをセットアップします。

    // attach our embedded assembly loader.
    AppDomain.CurrentDomain.AssemblyResolve += AssemblyManager.Instance.Resolver;

これが私の実際のリゾルバーです。

public Assembly Resolver(object sender, ResolveEventArgs args)
{
    AssemblyName askedAssembly = new AssemblyName(args.Name);

    lock (this)
    {
        Assembly assembly;

        string resourceName = string.Format("Assets.Assemblies.{0}.dll", askedAssembly.Name);
        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
        {
            if (stream == null)
            {
                LogManager.Instance.Write(LogMessageTypes.Fatal, string.Format("Can not resolve asked assembly: {0}", askedAssembly.Name));
                MessageBox.Show(i18n.CanNotLoadRequiredAssembliesMessage, i18n.CanNotLoadRequiredAssembliesTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(-1);
            }

            byte[] assemblyData = new byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            assembly = Assembly.Load(assemblyData);
        }

        LogManager.Instance.Write(LogMessageTypes.Trace, "Loaded embedded assembly: " + askedAssembly.Name);

        return assembly;
    }
}

これで、私のプログラムはこれらのライブラリ アセンブリを参照します。

  • Esent.Collections.dll
  • Esent.Interop.dll
  • HtmlAgilityPack.dll
  • Ionic.Zip.Reduced.dll
  • System.Windows.Forms.Calendar.dll
  • AxInterop.ShockwaveFlashObjects
  • Interop.ShockwaveFlashObjects
  • irrKlang.NET4.dll
  • ikpMP3.dll
  • Nini.dll (解決済み)

上記のリゾルバーを使用します。Esent.Collections、Esent.Interop、HtmlAgilityPack、Ionic.Zip.Reduced、System.Windows.Forms.Calendar、AxInterop.ShockwaveFlashObjects、Interop.ShockwaveFlashObjects を埋め込み、実行時にそれらを解決できます。

この問題は、irrKlang.NET.4、Nini、および ShockwaveFlash アセンブリで発生します。これらのアセンブリを埋め込んで実行時に解決しようとすると、問題が発生します。

irrKlangの場合、irrKlang.NET4アセンブリが管理されていないikpMP3.dllを参照しているため、問題を理解できます。これは、それ自体では見つけることができません。

Nini.dllの場合、実際にこのアセンブリを埋め込むことができ、VSデバッグ/リリース構成を使用して実行すると問題なく動作しますが、エクスプローラーから自分でプログラムを起動すると、プログラムは起動を拒否します(エラーやビットなし)の情報)。

どんな助けでも感謝します。

今すぐ更新 、Marc Gravell の回答に感謝します。Nini.dll をロードできます。

irrKlang 部分については、irrKlang.NET4.dll は ikpMp3.dll を必要とするマネージド アセンブリ (アンマネージド アセンブリ) であるため、実行時に irrKlang.NET4.dll を解決しようとすると、必要な依存関係 ikpMp3 にアクセスできます。これに対する回避策はありますか?

4

1 に答える 1

4

ここでの一般的な問題は、アセンブリ解決イベントを登録する前に型を使用することです。特に、システムがメソッドの実行を開始する前に、メソッドを JIT できる必要があることに注意してくださいMain()

そのため、エントリポイント ( Main()) がイベント フックを実行し、問題の型とも対話する場合、サブスクライブする前に(JIT 用に) 型を解決しようとするか、サブスクライブする機会があります。

メインで最小限のことを行います。「実際の」コードを別のメソッドに移動します。これは、イベントが確実にサブスクライブされた場合にのみ呼び出されます。

例えば:

static void Main() {
    SubscribeAssemblyResolver();
    ExecuteApplication();
}

極端な場合には、上記のメソッドのインライン化を無効にするために MethodImplAttribute を使用する必要さえあるかもしれません。

于 2011-02-12T23:27:05.120 に答える