无法捕获MSScriptControl的Eval函数中引发的自定义异常

时间:2017-07-31 04:13:46

标签: c# msscriptcontrol

这是我的问题的MVCE。

我有这个方法使用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子句。但是,我得到了一个通用Exception(我使用GetType().Name验证了例外类型),消息为"不能除以零"代替。

我确实在Evaluator类中遇到以下错误:

  

类型' Library.CustomException'的例外情况发生在XXX.dll中但未在用户代码中处理

如果我像这样修改我的DoCalculate()那么我可以很好地捕获一个CustomException:

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

这是否意味着无法从Eval函数中定义和抛出我自己的异常?

我使用的是.NET 4.6.2和Interop.MSScriptControl 1.0.0.0

1 个答案:

答案 0 :(得分:2)

这是此link

中给出的答案摘要

COM方法通过返回HRESULTs报告错误; .NET方法通过抛出异常来报告它们。运行时处理两者之间的转换。 .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;
    }
}