2011-09-09 13 views
4

マイタスク:dllファイルまたはexeファイル内のすべてのフォーム(WindowsフォームまたはWPF、重要ではありません)を検索し、そのリストを返します。理論的にはうまくいきます(つまり、WPFやWindowsFormでアセンブリを作成した場合、フォーム、テキストボックス、ラベルなどをすべて取得できます)。 「実際の」アセンブリになると失敗します。 GetExportedTypes()を "カスタム"アセンブリごとに呼び出すと、FileNotFound例外が発生します(.NETアセンブリが見つかっても問題はありません)。私は既にGetReferencedAssemblies()を使用して、参照されているアセンブリ(Reflection.Assembly.LoadFrom)を読み込みます。それは動作します(すべてのアセンブリが見つかってAppDomainに読み込まれます)。GetExportedTypes()FileNotFoundException:アセンブリが見つかりません

バージョン番号(一致する)を確認して、実行可能ファイルとアセンブリを、参照されているすべてのアセンブリを含む1つのディレクトリにコピーしましたが、動作しません。

foreach (AssemblyName reference in selectedAssembly.GetReferencedAssemblies()) 
{ 
     if (System.IO.File.Exists(
      System.IO.Path.GetDirectoryName(selectedAssembly.Location) + 
       @"\" + reference.Name + ".dll")) 
     { 
     System.Reflection.Assembly.LoadFrom(
      System.IO.Path.GetDirectoryName(selectedAssembly.Location) + 
       @"\" + reference.Name + ".dll"); 
     } 
     else if (System.IO.File.Exists(@"C:\dll\" + reference.Name + ".dll")) 
     { 
     System.Reflection.Assembly.LoadFrom(@"C:\dll\" + reference.Name + ".dll"); 
     } 
     else 
     { 
     System.Reflection.Assembly.ReflectionOnlyLoad(reference.FullName); 
     } 

     selectedAssembly.GetExportedTypes();  
} 

最初のチェックイン時に参照されたDLLがアセンブリがあるディレクトリに存在する場合、かどうかを確認されていない場合:ここでは

が私のコードで、多分誰かが私は(明らかに)間違ってやって割り出しそれはC:\ dllに存在し、それがなければGACを試してみてください。それは動作し、そこからエラーはありませんが、GetExportedTypesに来るとすぐに、最初のカスタムライブラリのFileNotFound例外が発生します。

*編集1私は「本当のアセンブリ」によって何を意味するか:私はfuslogvw-をするヒントをありがとう、より複雑なアセンブリを意味し、non-standard-.NETライブラリ/アセンブリへの参照


を持っています.exe Hans Passantが、「このようなコードで」とはどういう意味ですか?


大丈夫私はFuslogvw.exeではを使用して、私は「selectedAssembly」で参照されているすべての単一のdllのための2つの例外を取得します。 最初のものは他ませんlogEntryがselectedAssemblyが参照するDLLがなかったことを言う

のようなもの「LoadFromコンテキスト で結合開始システムが所有する画像がLoadFrom・コンテキストで検索されていない」と言いますアプリケーションの基本パスとその下のすべてのディレクトリからダウンロードしようとしましたが、実際の場所からではありませんでした。重要な質問:どのようにLoad-contextをLoadFromに変更しますか?なぜ.NETはこれほど頑固なのですか?つまり、アセンブリがAppDomainにロードされているため、アセンブリの実際の位置を気にする必要はありません。


大丈夫です。 http://ayende.com/blog/1376/solving-the-assembly-load-context-problem

これを私の既存のクラスに実装しました(静的キーワードを削除し、Initメソッドの本体を自分のメソッドに入れてコンパイルしました)。

あなたの助けを借りてくれてありがとう。

+0

からのソースコードは、あなたがこれをトラブルシューティングするために「本当のアセンブリ」 –

+3

使用Fuslogvw.exeではによって何を意味するのです。依存しているアセンブリのものを含め、どのバインディングが失敗したかを示します。このようなコードの通常の問題。 –

答えて

3

問題は解決しました。http://ayende.com/blog/1376/solving-the-assembly-load-context-problem

これを既存のクラスに実装しました(静的キーワードを削除し、Initメソッドの本体を自分のメソッドに入れてコンパイルしていました)。

あなたの助けを借りてくれてありがとう。

ウェブサイトは、いつの日か使用できなくなります念のために、ここでayende

static Dictionary<string, Assembly>assemblies; 

public static void Init() 
{ 

    assemblies = new Dictionary<string, Assembly>(); 

    AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad); 

    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 
} 

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
{ 

    Assembly assembly = null; 

    assemblies.TryGetValue(args.Name, out assembly); 

    return assembly; 

} 

static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args) 
{ 

    Assembly assembly = args.LoadedAssembly; 
    assemblies[assembly.FullName] = assembly; 
} 
2

Reflectorを使用して、ロードしていない参照を確認することをおすすめします。たとえば、現在のアセンブリが参照している参照されているアセンブリのみを読み込みます。あなたは、参照されたアセンブリを見つけるために各子供を辞任しますか? FileNotFoundエラーは、おそらく、ロードされていない別のアセンブリで宣言されている型の方向を示しています。

+0

ええ、ありがとう。 foreachループを再帰的ループとして再構築します。しかし、それは本当に問題になることができますか?つまり、アセンブリはエラーなしでAppDomainにロードされ、選択されたアセンブリでは「GetExportedTypes」のみ呼び出され、ほかのアセンブリでは呼び出されません。 –

+0

申し訳ありません、それは問題ではありませんでした。 LoadContextが問題でした;) –

関連する問題