0

这个问题的根本原因是什么?CSharpOptParse、XslTransform.Transform(...) 还是 NUnit?如果这个问题无法修复,我可以使用其他什么等效的库来代替它,这是积极支持的?

我正在使用CSharpOptParse的 1.0.1 版本,它最后一次修改是在 2005 年 2 月。

我有以下类(当然为本示例进行了简化)与 CSharpOptParse 一起使用:

public enum CommandType
{
   Usage
}

public class Options
{
   [OptDef(OptValType.Flag)]
   [LongOptionName("help")]
   [Description("Displays this help")]
   public bool Help { get; set; }

   public CommandType CommandType
   {
      get { return CommandType.Usage; }
   }
}

这是一些复制问题的单元测试代码:

TextWriter output = Console.Out;

Options options = new Options { Help = true };
Parser p = ParserFactory.BuildParser(options);
p.Parse();

output.WriteLine("Usage: Console [--a]");
UsageBuilder builder = new UsageBuilder();
builder.BeginSection("Arguments:"); 
builder.AddOptions(p.GetOptionDefinitions()); //could the issue be created here?
builder.EndSection();
builder.ToText(output, OptStyle.Unix, true); //The problem occurs here

我是否有可能通过没有使用正确的部分设置 UsageBuilder 来导致问题?可能这可能会导致 xslt 文件出现问题???

当我运行该代码时,出现以下异常:

    System.Xml.XPath.XPathException : Function 'ext:FormatText()' has failed.
    ----> System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
      ----> System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: startIndex
       at MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator)
       at System.Xml.Xsl.XsltOld.Processor.ValueOf(ActionFrame context, Int32 key)
       at System.Xml.Xsl.XsltOld.ValueOfAction.Execute(Processor processor, ActionFrame frame)
       at System.Xml.Xsl.XsltOld.ActionFrame.Execute(Processor processor)
       at System.Xml.Xsl.XsltOld.Processor.Execute()
       at System.Xml.Xsl.XsltOld.Processor.Execute(TextWriter writer)
       at System.Xml.Xsl.XslTransform.Transform(XPathNavigator input, XsltArgumentList args, TextWriter output, XmlResolver resolver)
       at System.Xml.Xsl.XslTransform.Transform(IXPathNavigable input, XsltArgumentList args, TextWriter output, XmlResolver resolver)
       at CommandLine.OptParse.UsageBuilder.ToText(TextWriter writer, OptStyle optStyle, Boolean includeDefaultValues, Int32 maxColumns)
--TargetInvocationException
    at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
    at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
    at System.Xml.Xsl.XsltOld.XsltCompileContext.FuncExtension.Invoke(XsltContext xsltContext, Object[] args, XPathNavigator docContext)
    at MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator)
    --ArgumentOutOfRangeException
    at System.String.LastIndexOfAny(Char[] anyOf, Int32 startIndex, Int32 count)

我不知道是什么导致了这个问题....最奇怪的部分是它只发生在我的 NUnit 测试中。当通过“Console.exe --help”调用此代码时,它运行良好,没有异常。我看不出 CSharpOptParse 有什么问题,所以这可能是 .NET 的 XslTransform 类或 NUnit 中的问题吗?

有没有其他人遇到过这个问题?有人对如何追踪问题或切换到更好的图书馆有任何建议吗?

4

3 回答 3

1

我知道这是一个老问题。但..

导致异常的原因是该ToText()方法尝试确定控制台的宽度,并且当您写入任何不是真正的控制台时它会失败。

修复很简单:设置固定宽度。

将对 ToText 的调用更改为:

try
{
    usage.ToText(Console.Out, OptStyle.Unix, true);
}
catch
{
    usage.ToText(Console.Out, OptStyle.Unix, true, 90);
}

现在,如果正常调用失败,它将尝试故障安全调用。

于 2011-12-29T22:11:01.340 回答
0

为什么不将调试器附加到 NUnit,打开 First-Chance 异常,然后找出发生了什么?

于 2009-01-28T02:00:23.997 回答
0

我遇到了同样的问题,似乎已经解决了(不确定这样做会导致什么问题,但一切似乎都正常)。

寻找:

public TextTransformHelper(int maxColumns)
        {
            _maxColumns = maxColumns;

            if (_maxColumns == -1)
            {
                // try to determine console width
                string os = Environment.GetEnvironmentVariable("OS");

                if (os != null && os.StartsWith("Win"))
                {
                    ConsoleUtils.ConsoleHelper ch = new ConsoleUtils.ConsoleHelper();
                    _maxColumns = ch.GetScreenInfo().Size.X;
                }
            }
        }

然后将其修改为以下内容:

public TextTransformHelper(int maxColumns)
    {
        _maxColumns = maxColumns;

        if (_maxColumns == -1)
        {
            // try to determine console width
            string os = Environment.GetEnvironmentVariable("OS");

            if (os != null && os.StartsWith("Win"))
            {
                ConsoleUtils.ConsoleHelper ch = new ConsoleUtils.ConsoleHelper();
                _maxColumns = ch.GetScreenInfo().Size.X;
                if(_maxColumns == 0) //added
                    _maxColumns = -1; //added
            }
        }
    }

它爆炸的原因是因为在 FormatText 函数中,它具有以下 if 语句,如果未定义列宽或为 -1,则该语句应该被命中。对我来说,该函数将始终返回 0,这将导致下面的 if 语句不被命中,然后导致“ArgumentOutOfRange”异常。这是在 Windows Server 2008 上:

if (_maxColumns == -1)
                {
                    output.Append((first) ? indentStr : handingIndentStr);
                    output.Append(line);
                    output.Append(Environment.NewLine);
                    first = false;
                    continue;
                }

我能够通过查看“ext:FormatText”失败错误然后在所有 FormatText 函数(xslt 正在调用 C# 函数)上设置断点来调试它,然后查看异常并进一步调试。

我希望这有帮助。

约翰·雷内迈尔

于 2009-07-08T17:18:52.217 回答