web-dev-qa-db-ja.com

System.TypeLoadExceptionの原因は何ですか?

私は、OS#のようなWindows CE 5.0を使用するバーコードスキャナーを備えたモバイルコンピューターであるHoneywell Dolphin 6100用のアプリケーションをC#を使用してVS2008で開発しています。

ローカルデバイスから遠隔サーバーにファイルを送信できる機能を追加したい。これを保証できるライブラリー「 Tamir.SharpSSH 」を見つけました。コンソールアプリケーションと通常のWindowsフォームアプリケーションでコードをテストしましたが、完全に機能します。しかし、winCEデバイスで同じコードを使用しようとすると、TypeLoadExceptionが発生し、エラーメッセージが表示されます。

アセンブリ 'Tamir.SharpSSH、
 Version = 1.1.1.13、Culture = neutral、PublicKeyToken = null'からタイプ 'Tamir.SharpSsh.SshTransferProtocolBase'をロードできませんでした。

私が使用しているコードは以下のようなものです:

SshTransferProtocolBase sshCp = new Scp(Tools.GlobalVarMeth.hostName, Tools.GlobalVarMeth.serverUserName);
sshCp.Password = Tools.GlobalVarMeth.serverUserpassword;
sshCp.Connect();

string localFile = Tools.GlobalVarMeth.applicationPath + "/" + fileName + ".csv";
string remoteFile = Tools.GlobalVarMeth.serverRemoteFilePath + "/" + fileName + ".csv";

sshCp.Put(localFile, remoteFile);

sshCp.Close();

誰もこれについて何か考えがありますか?本当に感謝します!!!

22
J.M.J

それはいくつあってもかまいません。考えられる原因は次のとおりです。

  • アセンブリが見つかりません
  • アセンブリが依存しているアセンブリが見つかりません
  • アセンブリは見つかりましたが、タイプは含まれていません
  • 型の静的コンストラクターは例外をスローします

最善の策は、Fusionログビューアを使用して診断することです。ドキュメントはこちらです:

http://msdn.Microsoft.com/en-us/library/e74a18c4(v = vs.110).aspx

(FYI "Fusion"は、アセンブリ読み込みシステムを設計したチームのコード名でした。コード名が最終製品のファイル名になったのは少し残念です。 "AssemblyBindingLogViewer.exe"またはそのようなもの。)

36
Eric Lippert

Eric Lippertの答えは状況を完全に説明しています。

通常、この例外に関するヘルプページでカバーされていないケースについて、簡単な回答を追加します。

私はいくつかのオープンソースのもの(Akka.Net、名前を付ける)のための迅速で汚いテストプロジェクトを作成し、プロジェクト自体に「Akka」という名前を付けました。

完全にビルドされますが、起動時にAkka.dllのクラスに関するタイプロード例外をスローします。

これは、実行可能ファイル(akka.exe)と参照(akka.dll)の名前が同じだからです。これを理解するのに数分かかりました(ローカルのコピー、ターゲットプラットフォーム、正確なバージョンなどのことから始めました)。

それは非常に馬鹿げたものですが、強制的に最初に考えるものではありません(特に依存関係にナゲットを使用したので)、それを共有することは興味深いと思いました:EXEと依存関係が同じ名前の場合、TypeLoadExceptionが発生します。

23
AFract

これはほとんど私を夢中にさせました...

これをどのように管理したかわかりませんが、何らかの理由で古いバージョンのDLLがGACにありました。古いアセンブリを探して削除してみてください。

幸運を祈ります!

3
Hudson

これは、さまざまな原因で発生する可能性があります。MSDNでは次のように述べています。

TypeLoadExceptionは、共通言語ランタイムがアセンブリ、アセンブリ内の型を検出できない場合、または型をロードできない場合にスローされます。

そのため、アセンブリが見つからないか、タイプが見つからないか、ランタイム構成間で競合が発生しているので、タイプが見つからないことは明らかです。

参照しているアセンブリが、使用しているものとは異なるプラットフォームタイプ(32ビット/ 64ビットなど)であるため、問題が発生することがあります。

例外をキャッチして詳細を調べ、問題の原因を特定することをお勧めします。


以前の情報に加えて

時々、この問題が発生するのを見たことがあります(何らかの理由で)参照されたアセンブリは、参照およびロードされていても実際には解決できないためです。

私は通常、AppDomainの境界が関係しているときにこれを確認します。

この問題を時々解決する1つの方法(ただし、アセンブリが既にAppDomainにある場合のみ)は、次のコードスニペットです。

AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
{
   return AppDomain.CurrentDomain.GetAssemblies()
      .SingleOrDefault(asm => asm.FullName == e.Name);
}

先ほど言ったように、AppDomainsが関与するときにこの問題が発生します。アセンブリが実際に既に参照およびロードされている場合、これは解決するようです。フレームワークが参照自体の解決に失敗する理由がわかりません。

3
Clint

レジストリでいくつかの設定を有効にすると、.NET Compact Frameworkからローダーログファイルを取得できます。 Power Toys for .NET Compact Framework には、レジストリ値を設定するNETCFLoggingというツールが含まれています。

レジストリ値は次のとおりです。

http://msdn.Microsoft.com/en-us/library/ms229650(v = VS.90).aspx

1
Mike Dimmick

名前(名前空間、クラス名など)が本来の名前であることを確認してください。プロジェクトで最初からやり直さなければならなかったときにこのエラーが発生し、クラスの内容をテンプレートからコピーし、クラス名を「テンプレートクラス」から正しい名前に変更できませんでした(プロジェクト名と一致するはずでした) 。

0
makesha.laun

私の場合の問題は、1つのソリューションで同じライブラリを使用する2つのプロジェクトがあったことです。最初のプロジェクトでのみDLLを更新しました。したがって、ソリューションをビルドすると、2番目のプロジェクトは最初のプロジェクトからのDLLをオーバーライドします(プロジェクトのビルド順序)。

例:

溶液:

--MainProject

------ MyDll v5.3.2.0

- プロトタイプ

------ MyDll v5.0.0.0

2番目のプロジェクトでDLLを更新した後に問題が発生しました。

0
Mroczny Arturek