2009-01-28 38 views
0

這個問題的根本原因是什麼? CSharpOptParse,XslTransform.Transform(...)或NUnit?如果這個問題是不可修復的,那麼我可以使用什麼其他等效庫?僅當在NUnit測試中使用時,爲什麼CSharpOptParse UsageBuilder因XPathException而失敗?

我使用的CSharpOptParse 1.0.1版本,這是最後一次修改於2005年二月

我已經有下面的類(簡化當然這個例子中)與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中的問題?

是否有其他人遇到過這個問題?有沒有人有任何建議如何找出問題或切換到更好的圖書館?

+0

我還沒有找到這個問題的答案......我不認爲我會得到很多的迴應,如果我把它賞金。有沒有人知道爲什麼會發生這種情況? – mezoid 2009-03-26 23:55:12

回答

1

我知道這是一個老問題。但..

異常是因爲ToText()方法試圖確定控制檯的寬度,並且在寫入任何非真實控制檯時失敗。

修復很簡單:設置一個固定的寬度。

更改調用ToText到:

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

現在,如果正常的調用失敗,它會嘗試自動防故障之一。

+0

抱歉花了這麼長時間來回復...已經有一段時間了,因爲我不得不處理這個問題......但我可以確認你說的是這樣的情況,它確實解決了這個問題。 – mezoid 2012-03-28 05:50:37

0

爲什麼不附加一個調試器到NUnit,打開First-Chance異常,並找出發生了什麼?

+0

我不太清楚如何做到這一點。我只知道如何將調試器附加到我的項目中......我所知道的最好的方法是逐步調試窗口中的代碼......但是在我無法涉足的位置發生異常。如果你能啓發我,那會很棒。 – mezoid 2009-01-28 02:09:08

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功能的原因,它具有以下,如果這是應該的語句如果列寬未定義或爲-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; 
       } 

我能夠看到「分機:FormatText」調試它失敗的錯誤,然後在所有FormatText功能設置斷點(在XSLT中調用C#功能),然後看在異常和進一步調試。

我希望這會有所幫助。

John Rennemeyer