-5

我有一个非常奇怪的“错误”,我不知道它可能是什么。应用程序是使用 .net 4 框架使用 VS2010 制作的。除了普通程序集,它还使用 MS 互操作 for excel。我在客户端计算机上安装了 Office 2010。

基本上,应用程序解析 excel 表并制作另一个(新文件)结果。问题:当我将 exe 文件复制到桌面(或 PC 上的任何其他位置)时,它会抛出异常,但是当它在存档 (RAR) 中并且存档在桌面上时,它可以正常工作。

我无法安装它,因为他们的系统(电话公司)非常严格,根本不应该使用该应用程序。(工人手动解析,一般需要3个小时,而程序5秒,所以老板不知道,因为他认为他们都很努力:))。

该问题在公司内的其他机器上仍然存在,因此不是孤立的情况。

任何有关它的信息都会受到赞赏。PS如果需要更多信息,请大声疾呼。这是未处理异常的“详细信息”。

有关调用即时 (JIT) 调试而不是此对话框的详细信息,请参阅此消息的末尾。

************** 异常文本 ************** System.ArgumentOutOfRangeException:索引和长度必须引用字符串中的位置。参数名称:System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy) at System.String.Substring(Int32 startIndex, Int32 length) at ExcelSvjetlana.Form1.buttonObradi_Click(Object sender, EventArgs e) at System.Windows 的长度.Forms.Control.OnClick(EventArgs e) 在 System.Windows.Forms.Button.OnClick(EventArgs e) 在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs 事件) 在 System.Windows.Forms.Control.WmMouseUp(Message& m,MouseButtons 按钮,Int32 点击)在 System.Windows.Forms.Control.WndProc(Message& m) 在 System.Windows.Forms.ButtonBase.WndProc(Message&

************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.239 (RTMGDR.030319-2300)
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
ExcelSvjetlana
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Users/sobradovic/Desktop/Interno.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.276 built by: RTMGDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.258 built by: RTMGDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Data
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll
----------------------------------------
System.Core
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Xml
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Numerics
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
   CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Numerics/v4.0_4.0.0.0__b77a5c561934e089/System.Numerics.dll
----------------------------------------
Microsoft.Office.Interop.Excel
    Assembly Version: 14.0.0.0
    Win32 Version: 14.0.4756.1000
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.Office.Interop.Excel/14.0.0.0__71e9bce111e9429c/Microsoft.Office.Interop.Excel.dll
----------------------------------------
office
    Assembly Version: 14.0.0.0
    Win32 Version: 14.0.4760.1000
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/office/14.0.0.0__71e9bce111e9429c/office.dll
----------------------------------------
Microsoft.CSharp
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.CSharp/v4.0_4.0.0.0__b03f5f7f11d50a3a/Microsoft.CSharp.dll
----------------------------------------
System.Dynamic
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Dynamic/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Dynamic.dll
----------------------------------------
Anonymously Hosted DynamicMethods Assembly
    Assembly Version: 0.0.0.0
    Win32 Version: 4.0.30319.239 (RTMGDR.030319-2300)
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/mscorlib/v4.0_4.0.0.0__b77a5c561934e089/mscorlib.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.
For example:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.

这是你要求的代码。请注意,我确实更改了一些字符串。

private void buttonObradi_Click(object sender, EventArgs e)
{
    int brojac = 0;
    string grade = "";
    string grading1 = "2";
    string grading2 = "3";
    string grading3 = "4";
    string grading4 = "1";
    string grading5 = "No Answer";
    string grading6 = "5";
    string grupa = "";
    bool citaj = false;
    bool mozda = false;
    string odjel = "";
    string pododjel = "";
    string ocjenica = "";
    int prviProlaz = 0;

    foreach (DataRow redak in excelData.Rows)
    {
        if (prviProlaz > 0)
        {
            if (brojac == 0)
            {
                brojac = 1;
                grupa = redak[1].ToString();
                mozda = false;
                citaj = false;
            }
            else
            {
                if (redak[1].ToString() == "")
                {
                    mozda = true;
                    citaj = false;
                }
                else
                {
                    if (redak[1].ToString() == "Agent Name")
                    {
                        citaj = true;
                    }
                    else if (redak[1].ToString() == grading1 || redak[1].ToString() == grading2 || redak[1].ToString() == grading3 || redak[1].ToString() == grading4 || redak[1].ToString() == grading5 || redak[1].ToString() == grading6)
                    {
                        grade = redak[1].ToString();
                        mozda = false;
                    }
                    else if (mozda == true)
                    {
                        brojac = 0;
                    }
                    else if (citaj == true)
                    {
                        if (grupa == "Team A" || grupa == "Team M" || grupa == "Team T")
                        {
                            pododjel = "AAAA";
                            odjel = "CCCC";
                        }
                        else if (grupa == "Team 1" || grupa == "Team 2")
                        {
                            pododjel = "BBBB";
                            odjel = "TTTT";
                        }
                        else if (grupa == "K Team" || grupa == "F Team")
                        {
                            pododjel = "RRRR";
                            odjel = "SSSS";
                        }
                        else if (grupa == "Group 1" || grupa == "Group 2" || grupa == "Group 3" || grupa == "Group 4")
                        {
                            pododjel = "FFFF";
                            odjel = "TTTTT";
                        }
                        else if (grupa == "Fun group 1" || grupa == "fun group 2" || grupa == "fun group 3" || grupa == "fun group 4" || grupa == "fun group 5")
                        {
                            pododjel = "KKKK";
                            odjel = "FFFF";
                        }
                        ocjenica = ocjenica.Trim();

                        preSort.Rows.Add(redak[0].ToString(), redak[1].ToString(), "", grade, Convert.ToDecimal(redak[4].ToString()), grade.Substring(0, 1), grupa, pododjel, odjel);
                    }
                }
            }
        }
        else
        {
            prviProlaz = 1;
        }
    }
    dataGridView2.DataSource = preSort;
}
4

7 回答 7

4

您遇到的问题似乎是Substring参数无效的操作。无论如何,这就是错误。

那行代码在做什么buttonObradi_Click?也许您遇到的问题是因为您要打开的文件的相对路径错误。或者你的exe的路径,更有可能。就像,您搜索第四个反斜杠并Substring从那里执行...如果您的 exe 位于少于 4 个反斜杠的路径中,那么您就有麻烦了 :) 只是一个例子。

编辑:事实上,Substring确实会产生错误,并且代码中唯一的子字符串是grade.Substring(0, 1). 所以等级必须为空。你说这只发生在某些机器上,所以我的猜测是,那台机器上的excel格式不同。据我可以从代码中确定,您解析 Excel 并期望在grade“代理名称”之前出现的行。如果:

else if (redak[1].ToString() == grading1 || redak[1].ToString() == grading2 || redak[1].ToString() == grading3 || redak[1].ToString() == grading4 || redak[1].ToString() == grading5 || redak[1].ToString() == grading6)

必须先通过并初始化成绩,在此行之前:

if (redak[1].ToString() == "Agent Name")

设置你citaj为真。否则你的grade变量永远不会被初始化,当然 Substring 会失败。

我希望我理解正确,我还没有真正调试过整个代码。所以我认为你应该检查机器上的excels这不起作用,看看它们是否错误,或者你需要调整你的代码以匹配该格式。但我仍然不明白为什么这会在 RAR 中起作用而不是在它之外......

于 2012-12-04T13:37:40.400 回答
2

堆栈跟踪导致我们看到错误与 Obradi 按钮单击Substring错误地调用方法有关(可能是因为字符串为空):

System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
at System.String.Substring(Int32 startIndex, Int32 length)
at ExcelSvjetlana.Form1.buttonObradi_Click(Object sender, EventArgs e)

错误消息允许我们看到它的OutOFRange异常,并且开始/停止字符串提取是一个问题:

System.ArgumentOutOfRangeException:索引和长度必须引用字符串中的位置。

当我们检查使用时,grade.substring我们可以看到它的状态可能是空的、空的或等等(afaik 它的空)。

解决方案

将行添加到数据表以绑定到 dataGridView2 时,在此行上放置一个条件断点以确保等级字符串变量不是string.IsNullOrEmpty(grade)

preSort.Rows.Add(redak[0].ToString(), redak[1].ToString(), "", grade, Convert.ToDecimal(redak[4].ToString()), grade.Substring(0, 1), grupa, pododjel, odjel);

当您无法在本地开发环境中重现问题时,您需要添加日志记录和异常处理。

将其放入foreach(DataRow redakTry-Catch 中。然后声明一个dr范围超出 try-catch 的变量并分配redakdr每次迭代。然后在 try-catch 异常处理程序中吐出 excel 电子表格dr行的详细信息,以便您可以跟踪它并在调试器中重现它,例如:

    DataRow dr;
    try
    {
       foreach (DataRow redak in excelData.Rows)
       {
          dr = redak;
       ...
       }
    }
    catch (Exception ex)
    {
         WriteToLog("Event: buttonObradi_Click. Problem with importing excel spreadsheet row: " + dr[0].ToString() + "\r\n Error: " + ex.Message);
    }
于 2012-12-24T11:26:00.140 回答
2

当您双击 rar 中的 .exe 文件(在 winrar 或 7zip 中)时,所有 rar 文件内容都将提取到本地临时文件夹中的一个新文件夹中,如下所示的文件夹:C:\Users\~ user名称 ~\AppData\Local\Temp\Rar$EX00.744\

因此,您需要检查此文件夹,并查看可能有助于运行应用程序的文件。

它可能正在加载不同的 excel 文件,您尚未共享该部分代码。

于 2012-12-25T18:20:19.397 回答
0

显然,你Substring()用错误的参数调用——可能startIndex太小或太大。或者它length太大(或太小)。.NET 的实现Substring总是困扰着我——我宁愿让它返回string.Empty而不是抛出;所以你可以在打电话之前插入支票Substring()或......

public static string SubstringFixed(this string str, int startIndex, int length)
{
    if (startIndex >= str.length || startIndex < 0)
    {
        return string.Empty;
    }
    length = Math.Min(length, str.Length - startIndex);
    length = Math.Max(length, 0);

    return str.Substring(startIndex, length);
}

在实用程序类的某处声明此方法,然后使用s.SubstringFixed()而不是s.Substring- 它只会返回""而不是抛出ArgumentOutOfRangeException坏情况。

哦,当然,当您使用字符串时,您应该始终确保正确处理空字符串......无论“正确”代表什么。通常它只是“不要崩溃,实际上什么也不做”。

于 2012-12-04T13:48:13.000 回答
0

我不认为这个问题是因为代码中有问题。

请确保您在代码使用的存档(RAR)中没有 excel 文件(或任何其他文件)。

于 2012-12-24T11:10:33.027 回答
0

正如其他人在您调用grade.Substring(0,1) 时提到的这个问题,而grade 是一个空字符串。毫无疑问,它是代码中唯一可以引发此异常的方法的调用。您绝对应该使用 Try Catch 块包围此方法以优雅地失败。

在您的代码中,当等级为空时,IE 长度为 0,并且您尝试访问将引发异常的等级 [0]。

如果输入格式错误,ToDecimal 也会引发异常,因此您也需要优雅地检查输入。再一次,一个 Try Catch 块会创造奇迹,让你的程序继续运行,而只错过这一行。

如果这是从 RAR 文件中提取后 EXE 出现的问题,那么您将得到一个损坏的可执行文件。我不确定您的应用程序如何加载一个 excel 文件,但如果它自动尝试从当前目录加载一个 excel 文件,您可能在 temp 文件夹中有一个正确的 excel 文件(这是您从 RAR 文件执行时 EXE 所在的位置)

于 2012-12-24T15:39:15.687 回答
0

最后我明白了。这是由于特权。Rar 有它,而我的应用程序没有安装并且没有文件夹的权限。因此发生了错误。仍然不知道为什么任何方法都会使用磁盘上的内存空间。

正如我所说,字符串函数不是问题。

于 2015-04-28T08:41:12.663 回答