1

C#アプリに依存関係がない場合、この「モジュールが見つかりませんでした」というエラーダイアログが報告されます。残念ながら、このダイアログには、見つからなかったファイルの名前が含まれていません。この場合、欠落している依存関係はDirectXdllD3DCompiler_43.dllでした。顧客が「モジュールが見つかりませんでした」と報告した場合、それはあまり役に立ちませんが、ファイルの名前が見つからなかったと報告した場合、少なくとも手がかりが得られます。

この例外をキャッチして、見つからなかったファイルの名前を含むエラーダイアログを生成できますか?これはアプリケーションの起動の早い段階(メインの前)に発生するので、どうすればこれを実行できますか?

エラーダイアログ

4

5 に答える 5

2

AssemblyResolveアプリケーションが必要なアセンブリを見つけられないときに発生するイベントをサブスクライブしてみてください。このイベントのハンドラーでは、アセンブリの名前やその他の必要な情報を含む独自のメッセージボックスを提供できます。

public static void Main()
{            
     AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyNotFoundEventHandler);

     InvokeExternalType();
}

private static Assembly ResolveEventHandler(object sender, ResolveEventArgs args)
{
    MessageBox.Show("Error, can't find assembly: " + args.Name, "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error);
    return null;
}

private static void InvokeExternalType()
{
    MyClass doc = ... // from an external assembly.
}

外部タイプ(欠落しているアセンブリに属している可能性があります)をmainメソッドで使用してはならないという問題が1つあります。そうしないと、イベントが発生しません。上記のコードサンプルに示されているように、別のメソッドでコード内でさらに呼び出す必要があります。

于 2012-12-03T23:31:13.250 に答える
2

コードを変更して再デプロイできる場合:

  • 新しいスタートアップクラス(Main()を使用するクラス)を作成します。プロジェクトのプロパティでそのクラスを選択していることを確認してください
  • システム外部のスタートアップクラスからの「使用」および外部参照がないことを確認します
  • 以前のスタートアップクラスのメインへの呼び出しの周りにtry/catchを置きます
  • 例外とすべての内部例外をメッセージボックス(またはデバッグログ)に出力します

    パブリッククラスMyNewEntryClass{

    public static void Main(){

      try{
          MyPreviousEntryClass.Main();
      } catch (Exception x){
         Exception ix = x;
         while (ix!=null){
            MessageBox.Show("Exception: "+ix);
            ix=ix.InnerException;
         }
      }
    

    }}

編集:あなたの例外はメッセージハンドラーから来ているようです。上記のコード編集は、コードの外部からのイベントを処理するすべてのイベントハンドラーを含む、すべてのエントリメソッドに適用できます(適用する必要があります)。上記のクラッシュ画面は、非同期で実行されたコードであるさまざまなハンドラーの例外に対して表示される可能性があります。たとえば、非同期呼び出しを使用するボタンハンドラーには、クラッシュウィンドウが表示されないように、2つの試行/キャッチが必要です。

private void Button_Clicked(object sender, EventArgs arg){
    try{
        Action<string> asyncCall = (s)=>{
            try{
                //...exception here will cause crash  
                // as it's not handled in Button_Clicked
            } catch (Exception xOnAsyncThread){
            }
        };
        asyncCall.BeginInvoke("outahere",null,null);
    } catch (Exception xOnUIThread){
    }
}

上記のステートメントは、Windowsメッセージ処理にも当てはまります。これは、外部イベントの単なる別のイベントハンドラーです。

コードを変更して再デプロイできない場合は、 Sysinternals Process Monitorを使用してください: http ://technet.microsoft.com/en-us/sysinternals/bb896645 アプリを監視し、ファイルが見つからないイベントを強調表示するように構成します(詳細については、ドキュメントを参照してください)。 )。

ProcessMonitorが多すぎる場合は、例外メッセージからすべてのコンテンツをコピーして除外します-ロードされたものは問題ではありません

于 2012-12-04T21:02:22.933 に答える
1

プログラムでこれを行うことはできないと思います。ただし、マシンにアクセスできる場合は、「グローバルフラグ」をオンにして、「ローダースナップ」(ローダースナップの表示(Windowsデバッガー))と呼ばれるものを表示して、少なくとも問題を特定できます。

これは、その方法を説明する記事です。LoadLibraryの失敗のデバッグ

于 2012-12-03T09:03:25.407 に答える
1

顧客にexeファイルでdepends.exeを実行させ、結果をファイルに保存して、このファイルを送信します。

于 2012-11-21T12:11:36.057 に答える
1

いくつかのレジストリエントリを設定することでオンにできる「FuisonLog」があります。あらゆる種類のアセンブリのロードの問題を特定するのに役立ちます。必要なのは、顧客のPCからのログファイルだけです。詳細については、 https://stackoverflow.com/a/1527249/1288776
を 参照してください。 リンクが利用できない場合:次の値をHKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft\Fusion に追加します。


DWORD ForceLog set value to 1
DWORD LogFailures set value to 1
DWORD LogResourceBinds set value to 1
String LogPath set value to folder for logs ie) C:\FusionLog\

フォルダ名の後に円記号を含め、フォルダが存在することを確認してください。

于 2012-12-06T18:29:36.310 に答える