2009-09-15 7 views
24

私は誰かが私を助けることを望んでいる。私はCOMから特定のExceptionを取得し、それを捕まえてから何か他のことを試みる必要があります。他のすべては無視する必要があります。例外と私のエラーメッセージは次のとおりです。COMException固有のエラーコードをキャッチ

System.Runtime.InteropServices.COMException (0x800A03EC):マイクロソフトOffice Excel はファイル ':Test.xlsを\ C' にアクセスすることはできません。 いくつかの理由があります。

だから私の最初の試みは

try 
{ 
// something 
} 
catch (COMException ce) 
{ 
    if (ce.ErrorCode == 0x800A03EC) 
    { 
     // try something else 
    } 
} 

だったしかし、私は、コンパイラの警告をお読みください。整数 定数に

警告22比較は無意味ですが。定数は、私は0x800A03ECが HRESULT知っていると私はちょうどMSDN と読んで見てきた..... ExcelReader.cs 629今21

タイプ 「int型の範囲外の 次のとおりです。 重大度コード、機能コード、および エラーコード:

HRESULTは は、3つの異なるフィールドに分割され、32ビットの値です。重大度コード は、戻り値 が情報、警告、または エラーを表すかどうかを示します。ファシリティコードは、 のエラーの原因となるシステムの領域を示します。

私の究極の質問は、私がその特定の例外をトラップするようにするためですか?またはHResultからエラーコードを取得するにはどうすればよいですか?

ありがとうございます。

+0

メモを追加するだけです。この例外を再現するのはとても難しいことではありません。私はこれを行うために非常に具体的な設定が必要ですが、ここで質問することはもっと速いかもしれないと思っています:) – Ian

答えて

36

ErrorCodeは符号なし整数である必要があります。次のように比較を行うことができます。

try { 
    // something 
} catch (COMException ce) { 
    if ((uint)ce.ErrorCode == 0x800A03EC) { 
     // try something else 
    } 
} 
+0

C#コードからは、 WinErrorsOrWhatever'と 'if((uint)ce.ErrorCode == E_UNEXPECTED_OR_WHATEVER)'を使用していますか? – rturrado

+15

上記はうまく動作しますが、 'unchecked'文脈でコンパイルされたときだけです。さもなければ、負の 'ce.ErrorCode'はうまくいけば正の' uint'に変換されません。実際には '=='シンボルの反対側を変換し、 'if(ce.ErrorCode == unchecked((int)0x800A03EC)){...}'と言うと、より良いことです。 [MSDNの例](http://msdn.microsoft.com/en-us/library/system.exception.hresult.aspx)を参照してください。 –

+0

これはフレームワークのバグですか? Exception.HResultをuintとして定義する必要がありますか? – Tristan

0

を私は実際にそれは私が必要なシステム上で実行して取得するために管理し、エラーコードは-2146807284がわかりました。

これを見ると、0x800A03ECをバイナリに変換して2の補数として扱うと、値を計算できます。

+3

はい、代替方法は、HRESULTを符号付き整数に変換することですが、16進数のコードを残しておくと読みやすくなり(Googleに簡単になります)。 –

10

HRESULT値は、重大度コード、ファシリティコード、およびエラーコードの3つのフィールドに分割された32ビットを持ちます。重大度コードは、戻り値が情報、警告、またはエラーを表すかどうかを示します。 ファシリティコードは、エラーの原因となるシステムの領域を示します。 エラーコードは、例外を表すために割り当てられた一意の番号です。各例外は異なるHRESULTにマップされます。 抜粋:私が集まるものとhttp://en.wikipedia.org/wiki/HRESULT

、HRESULTビットの最初の半分は、例外が発生し、システム/プロセスに応じて変化してもよいです。後半にはエラータイプが含まれています。

try { 
    // something 
} catch (COMException ce) { 
    if ((uint)ce.ErrorCode & 0x0000FFFF == 0x800A03EC) { 
     // try something else 
    } 
} 

注:ので、上記のコードの構文エラーの疲れも、私はNETの男じゃない心に留めておいてください

コードは次のようになります。

+1

+1:詳しい内訳ありがとうございます。それはかなり前からのものですが、関心のある他の人にとっては役に立ちます。 – Ian

+7

「&0x0000FFFF」は何ですか? uintの左半分を '削除'(0に設定)するので、決して '== 0x800A03EC'にすることはできません。 –