AppDomain.CurrentDomain.AssemblyResolve が要求する .resourcesアセンブリ?質問する

AppDomain.CurrentDomain.AssemblyResolve が要求する .resourcesアセンブリ?質問する

コードを使用するサテライトアセンブリをEXEファイルに埋め込む方法csharptest.net によって提供されているカスタム アセンブリ リゾルバーを作成し、アセンブリをリソースに埋め込みました。

使用されているアセンブリは正常に解決できますが、何らかの理由で、AppDomain.CurrentDomain.AssemblyResolve が 'AppName.resources' というアセンブリ、具体的には "MyProgram.resources、Version=0.15.3992.31638、Culture=en-US、PublicKeyToken=null" を要求しますが、これを解決する方法がわかりません。

リソースからのカスタム アセンブリの読み込みを無効にし (すべてのアセンブリ dll をプログラム ディレクトリに配置しました)、AppDomain.CurrentDomain.AssemblyResolve を有効にしてみましたが、それでも要求されました。

これについては少し混乱しています。ご協力いただければ幸いです。

興味のある人のために私のコードをここに示します。

static Assembly ResolveAssemblies(object sender, ResolveEventArgs args)
{
    Assembly assembly = null;
    string name = args.Name.Substring(0, args.Name.IndexOf(','));
    if (name == "MyProgram.resources") return null;
    else name = string.Format("MyProgram.Resources.Assemblies.{0}.dll", name);

    lock (_loadedAssemblies)
    {
        if (!_loadedAssemblies.TryGetValue(name, out assembly))
        {
            using (Stream io = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
            {
                if (io == null)
                {
                    MessageBox.Show("MyProgram can not load one of it's dependencies. Please re-install the program", string.Format("Missing Assembly: {0}", name), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Environment.Exit(-1);
                }
                using (BinaryReader binaryReader = new BinaryReader(io))
                {
                    assembly = Assembly.Load(binaryReader.ReadBytes((int)io.Length));
                    _loadedAssemblies.Add(name, assembly);
                }
            }
        }
    }

    return assembly;
}

ベストアンサー1

自分で答える;

AssemblyInfo.cs にこの行を追加すると問題は解決され、リゾルバーはリソースを要求されなくなります。

[assembly: NeutralResourcesLanguageAttribute("en-US", UltimateResourceFallbackLocation.MainAssembly)]

これは回避策ではありますが、多言語アプリケーションの場合は慎重に検討する必要があります。

より詳しい情報:

このアプローチは、en-US 以外のカルチャを持つマシンでは失敗します。より良いアプローチは、アセンブリ リゾルバーのリソースを無視することです。

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

                string[] fields = args.Name.Split(',');
                string name = fields[0];
                string culture = fields[2];
                // failing to ignore queries for satellite resource assemblies or using [assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)] 
                // in AssemblyInfo.cs will crash the program on non en-US based system cultures.
                if (name.EndsWith(".resources") && !culture.EndsWith("neutral")) return null;

                /* the actual assembly resolver */
                ...
            }
      }

おすすめ記事