2017-07-31 15 views
2

これは私の問題のMVCEです。MSScriptControlのEval関数でスローされたカスタム例外をキャッチできません

MSScriptControlを使用していくつかの数式を動的に評価するこの方法があります。

public void DoCalculate() 
{ 
    try 
    { 
     var evaluator = new Evaluator(); 
     IScriptControl ctrl = new ScriptControl(); 
     ctrl.Language = "JavaScript"; 
     ctrl.AddObject("Evaluator", evaluator, false); 
     var calcFunction = "Number(Evaluator.Divide(4,0))"; 
     double rs = ctrl.Eval(calcFunction); 
    } 
    catch (CustomException cex) 
    { 
     // Handle CustomException. 
    } 
    catch (Exception ex) 
    { 
     // Handle general Exception. 
    } 
} 

これはEvaluatorクラスです。

public class Evaluator 
{ 
    public double Divide(int a, int b) 
    { 
     if (b == 0) 
     { 
      throw new CustomException("Cannot divide by zero"); 
     } 
     else 
     { 
      return a/b; 
     } 
    } 

    public void TestThrow() 
    { 
     throw new CustomException("This is a test"); 
    } 
} 

はこれがCustomExceptionクラスです:

using System; 

namespace Library 
{ 
    public class CustomException : Exception 
    { 
     public CustomException() 
      : base() 
     { 
     } 

     public CustomException(string message) 
      : base(message) 
     { 
     } 
    } 
} 

が、私はこのケースでCustomExceptionがスローされることが予想され、最初のcatch節が入力されます。しかし、私はExceptionGetType().Nameを使用して例外タイプを検証しました)というメッセージを "ゼロで割り切れません"というメッセージとともに表示しました。

私も評価者クラスに次のエラーを取得しました

型「Library.CustomException」の例外がXXX.dllで発生したが、私は場合は、ユーザコード

で処理されていませんでしたその後、私はちょうど罰金CustomExceptionをキャッチすることができ、このように)(私のDoCalculateを変更します。

public void DoCalculate() 
{ 
    try 
    { 
     var evaluator = new Evaluator(); 
     evaluator.TestThrow(); 
    } 
    catch (CustomException cex) 
    { 
     // Handle CustomException. 
    } 
    catch (Exception ex) 
    { 
     // Handle general Exception. 
    } 
} 

んが、自分の元を定義し、スローすることは不可能であることを意味内部の評価関数からのcept?

私はこれは、このlink

COMメソッドがHRESULTsを返すことでエラーを報告して与えられた答えをまとめたものです。NET 4.6.2およびInterop.MSScriptControl 1.0.0.0

+0

どのようにmsscriptcontrolが動作するのか分かりませんが、多少の集約型の例外ですか?あなたの '例外 'に内部例外はありますか? –

+0

@ChristianGollhardtいいえ、内部例外は空です。一般的な例外のメッセージは実際には私のCustomExceptionからです。 – tsukumogami

+0

実際にどんなタイプの例外がありますか? 「例外」のみ? 'ex.GetType()。Name' –

答えて

2

を使用しています。 .NETメソッドは、例外をスローすることによってそれらを報告します。ランタイムは、2つの間の移行を処理します。 .NET Frameworkの各例外クラスは、HRESULTにマップされます。だから、適切な例外をスローするには、次のことをお勧めします。

var evaluator = new Evaluator(); 
IScriptControl ctrl = new MSScriptControl.ScriptControl { Language = "VBScript" }; 
ctrl.AddObject("Evaluator", new Evaluator(), true); 
const string calcFunction = "Evaluator.Divide(4,0)"; 
try { 
    double rs = ctrl.Eval(calcFunction); 
} 
catch (DivideByZeroException ex) {//Actual DivideByZeroException from .Net 
    //How can you divide by zero?!?! 
} 
catch (Exception ex) { 
    //STUFF 
} 

public class Evaluator { 

    public double Divide(int a, int b) { 
     if (b == 0) { 
      throw new MyDivideByZeroException(); 
     } 
     return a/b; 
    } 
} 

public class MyDivideByZeroException : Exception { 

    public MyDivideByZeroException() { 
     HResult = -2147352558; 
    } 
} 
+0

私の実際のコードは、CustomExceptionは実際に定義されている.Net例外に対応していません。しかし、私は変更されたHResultで一般的なExceptionをスローして、そのコードが例外が実際に私のCustomExceptionであるかどうかを調べることを試みます。あなたは例外のHResultを乱すと、望ましくない効果を引き起こすと思いますか? – tsukumogami

+1

Com例外は.NET例外に自動的にマップされます。 HResultがあらかじめ定義されたHResultと一致しない場合は、汎用COM例外になります。 .Netには多くの例外が定義されていますが、そうでない場合、そのうちの1つがあなたのケースに一致する可能性があります。おそらく、あなたは 'ex.Message'プロパティを使ってそれがどのカスタム例外であるかを調べなければなりません。申し訳ありませんが、COM interopにはあまり慣れていません。( –

+0

本当にありがとうございました。私は正確なマッチを見つけられませんでしたが、確かに近くに十分なものがあります。 CustomExceptionクラスをこれ以上定義する必要があります。 – tsukumogami

関連する問題