我的C#应用程序在抛出未处理的异常时向我发送了一个堆栈跟踪,而我现在正在查看一个我不理解的内容。
看起来这不可能是我的错,但通常当我认为我后来被证明是错的时候。 8-)这是堆栈跟踪:
mscorlib caused an exception (ArgumentOutOfRangeException): startIndex cannot be larger than length of string.
Parameter name: startIndex
System.String::InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy) + 6c
System.String::Substring(Int32 startIndex) + 0
System.IO.Directory::InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption) + 149
System.IO.Directory::GetFiles(String path, String searchPattern, SearchOption searchOption) + 1c
System.IO.Directory::GetFiles(String path) + 0
EntrianSourceSearch.Index::zz18ez() + 19b
EntrianSourceSearch.Index::zz18dz() + a
所以我的代码(最后的混淆函数名称)调用System.IO.Directory.GetFiles(path)
,它会因字符串索引问题而崩溃。
可悲的是,我不知道传入的path
的价值,但不管怎样,System.IO.Directory::GetFiles
肯定不会像那样崩溃?尽我所能,我不能提出任何再现崩溃的GetFiles
的论据。
我是否真的在查看.NET运行时中的错误,或者是否有可能合法地导致此异常的内容? (如果在我调用GetFiles
时更改了目录,我可以理解出错的地方,但在这种情况下我不希望出现字符串索引异常。)
修改:感谢大家的想法!到目前为止最有可能的理论是,其中有一个带有狡猾的非BMP Unicode字符的路径名,但我仍然无法让它破裂。使用Reflector查看GetFiles
中的代码,我认为唯一可以解决的方法是GetDirectoryName()
返回更长的路径,即使输入是已完全正常化。离奇。我已经尝试用非BMP字符制作路径名(我从来没有一个名为{MUSICAL SYMBOL的目录)
在8-)之前的G CLEF}但我仍然无法让它休息。
我所做的是在失败的代码周围添加额外的日志记录(并确保我的日志记录与非BMP字符一起使用!)。如果它再次发生,我会有更多的信息。
答案 0 :(得分:2)
您可以尝试使用.NET Reflector查看System.IO.Path.GetFiles()
的代码。从快速查看,它显然只调用String.Substring()
从路径的末尾拆分并将其添加回方法的末尾附近。它会检查Path.DirectorySeparatorChar
(反斜杠,'\'
)和Path.AltDirectorySeparatorChar
(斜杠,'/'
)以确定子字符串的索引和长度。
我的猜测是无效或unicode文件或文件夹名称会混淆方法。
答案 1 :(得分:1)
只是一个猜测......作为参数传递的任何文件名是否超过256个字符? .Net框架标准System.IO函数无法处理比该文件更长的文件名。
答案 2 :(得分:1)
你说这只是这一个客户吗?
希望有所帮助,祝你好运!请告诉我们您找到的解决方案是什么,肯定会是一个有趣的解决方案。
答案 3 :(得分:1)
也许您可以提供有关客户遇到问题的一些详细信息。像: 1.操作系统名称和版本 2.操作系统语言 3.您要定位的.Net版本,与客户运行的.Net版本相比。
目录路径中可能有unicode字符导致字符串长度偏离一个或多个。
另一个注意事项:异常文本表明您的程序是用托管C ++编写的。你不是在混合任何非托管字符串操作吗?
我可能会建议您,如果可以,修改诊断程序以捕获导致错误的实际路径变量。 可能的合理解释:http://support.microsoft.com/kb/943804/
答案 4 :(得分:1)
首先也应该唯一的问题是,“你的奔跑ChkDsk吗?”
答案 5 :(得分:0)
也许它与混淆器有关。然后,食物会搞砸了。尝试在没有混淆器的情况下运行代码。并发布您的结果。
修改强> 你能重现崩溃吗?
答案 6 :(得分:0)
不确定这是否相关,但我在Visual C ++中使用GetFiles,在列出C:的内容时崩溃了,原来我有一个文件夹,其中包含先前安装的混乱权限。我将文件夹重新收回给当前用户,并修复了崩溃。
答案 7 :(得分:0)
从源和您的评论中,我怀疑UNC路径导致问题,可能存在安全权限或共享权限问题。例如,如果用户关闭了8.3文件名的创建,您肯定会遇到UNC路径问题,因为它会导致网络提供程序在Windows 2000和Windows XP中检索正确的文件名失败。 (我忘了修复了这个bug的服务包。)
以下是重要的源代码。
String tempStr = Path.InternalCombine(fullPath, searchPattern);
// If path ends in a trailing slash (\), append a * or we'll
// get a "Cannot find the file specified" exception
char lastChar = tempStr[tempStr.Length-1];
if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar || lastChar == Path.VolumeSeparatorChar)
tempStr = tempStr + '*';
fullPath = Path.GetDirectoryName(tempStr);
BCLDebug.Assert((fullPath != null),"fullpath can't be null!");
String searchCriteria;
bool trailingSlash = false;
bool trailingSlashUserPath = false;
lastChar = fullPath[fullPath.Length-1];
trailingSlash = (lastChar == Path.DirectorySeparatorChar) || (lastChar == Path.AltDirectorySeparatorChar);
if (trailingSlash) {
// Can happen if the path is C:\temp, in which case GetDirectoryName would return C:\
searchCriteria = tempStr.Substring(fullPath.Length);
}
else
searchCriteria = tempStr.Substring(fullPath.Length + 1);
答案 8 :(得分:0)
是否可以快速编写控制台应用程序并在调试模式下运行它。基本上使用GetFiles方法遍历整个文件目录。也许某些东西会被击中,你应该能够快速定位有问题的文件吗?