【问题标题】:A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll in windows 7 but not on xp在 Windows 7 中的 mscorlib.dll 中发生了“System.IO.IOException”类型的第一次机会异常,但在 xp 上没有
【发布时间】:2014-05-24 02:53:24
【问题描述】:

我在使用 .NET 4.0 的 Windows XP 下的 Visual Basic 2010 Professional 中运行良好的这段代码有点问题。但是,当此代码在 Windows 7 机器上运行时,我收到以下错误:

在 mscorlib.dll 中发生了“System.IO.IOException”类型的第一次机会异常

“在 Mscorlib.dll 中发生类型为 'System.IO.IOException' 的未处理异常”

我写的代码是用来将ListBox的内容写入文本文件的。

问题是文件没有被创建,或者当它被手动创建时,它没有被读取,这只发生在 Windows 7 中。

这是我写的代码:

   'at the very top
   Imports System.Net
   Imports System
   Imports System.Windows.Forms
   Imports System.Security.Permissions
   
   'in my form load
   If My.Computer.FileSystem.FileExists("C:\hitory.txt") Then
        Dim h As New IO.StreamReader("C:\hitory.txt")
        While (h.Peek() > -1)
            history.ListBox1.Items.Add(h.ReadLine)
        End While
        h.Close()
    Else
        'charge l'historique en mémoire
        Dim w As New IO.StreamWriter("C:\hitory.txt")
        Dim i As Integer
        For i = 0 To history.ListBox1.Items.Count - 1
            w.WriteLine(history.ListBox1.Items.Item(i))
        Next
        w.Close()
    End If

    If My.Computer.FileSystem.FileExists("C:\fav.txt") Then
        Dim f As New IO.StreamReader("C:\fav.txt")
        While (f.Peek() > -1)
            fav.ListBox1.Items.Add(f.ReadLine)
        End While
        f.Close()
    Else
        'charge les favorit en mémoire
        Dim z As New IO.StreamWriter("C:\fav.txt")
        Dim j As Integer
        For j = 0 To fav.ListBox1.Items.Count - 1
            z.WriteLine(fav.ListBox1.Items.Item(j))
        Next
        z.Close()
    End If
    textBox1.Items.AddRange(IO.File.ReadAllLines("C:\hitory.txt"))

【问题讨论】:

  • 查看文件夹和运行程序的权限;否则还要检查病毒扫描程序不是这里的瓶颈。

标签: .net vb.net


【解决方案1】:

在 Windows 7 机器上,UAC 正在启动。您的应用程序没有适当的权限来写入磁盘根级别的文件。

该错误在 Windows XP 中仍然存在,只是您的(默认)安全设置没有发现它。任何称职的系统管理员都会将系统配置为限制对磁盘根级别的访问,然后您就会回到 Windows 7 下的位置。

只有两种可能的修复方法:

  1. 向您的应用程序添加一个清单,表明它必须以管理权限运行。这将导致 UAC 在应用程序启动时提示提升。如果您的用户帐户具有管理权限,您将能够提升该进程,然后它将具有写入磁盘根级别的权限。否则,你就完蛋了——你甚至无法启动应用程序。

    这是错误的选择。您的应用程序不应该写入磁盘的根级别,因此坦率地说,通过引入一堆额外的复杂性来掩盖中心错误是愚蠢的。

  2. 修复代码,以便将文件保存在其他位置。 Application Data 文件夹是个好地方,除非最终用户需要能够查看/修改文件,否则您需要 My Documents 文件夹。

    您可以使用System.Environment.GetFolderPath method 获取这些文件夹的路径,它采用Environment.SpecialFolder 类型的枚举值,指定您要检索路径的文件夹。

    好的选择是:

    • SpecialFolder.ApplicationData 用于应与用户帐户一起漫游的特定于应用程序的数据。

    • SpecialFolder.LocalApplicationData 用于不应随用户帐户漫游的特定于应用程序的数据。

    • SpecialFolder.MyDocuments 用于用户应该能够查看/修改的应用程序创建的文档。

    获得路径后,使用System.IO.Path.Combine method 附加您的文件名。使用 that 路径来加载/保存文件。

哦,是的,正确拼写文件名:history.txt。 :-)

【讨论】:

  • 是的,但是访问冲突不会引发authorizedaccessexception而不是ioexception吗? :\ 起初,我认为这可能是权限问题,但现在我确定不是 ;o
【解决方案2】:

"C:\hitory.txt"

错字可能是你的问题。试一试,抓住:

Try
    ' code
Catch ax As UnauthorizedAccessException
    MsgBox("ax: " & ax.ToString)
Catch ix As IO.IOException
    MsgBox("ix: " & ix.ToString)
Catch ex As Exception
    MsgBox("ex: " & ex.ToString)
End Try

要追加,请指定“追加”参数。即:

Dim w As New IO.StreamWriter("C:\history.txt", True)

另外,为什么要使用 My.Computer.FileSystem,而不是 System.IO?它更快,更少抽象。

另外,我不喜欢这种偷看的东西。在您的情况下,我认为不需要它,请参阅我的其他帖子以了解 StreamReader/Writer 的用法:https://stackoverflow.com/questions/23792819/vb-code-to-parse-one-file-into-two-files/23816245#23816245

或者还有其他方法,它将返回一个 String() 数组,您可以轻松地将其转换为列表框的数据集或列表:http://msdn.microsoft.com/en-us/library/s2tte0y1%28v=vs.110%29.aspx

File.ReadAllLines("C:\history.txt")

编辑:正如 cmets 中提到的基于代码的(我还不能编写 cmets),权限也是一个可能的问题。

【讨论】:

  • 错字不太可能是问题所在。他始终犯了同样的错字,所以写入文件的代码实际上是写入文件名hitory.txt。因此,尝试读取文件的代码应该会找到它。此外,将整个事情放在 try/catch 中是没有用的。您在 catch 块中所做的唯一一件事就是显示一个消息框,默认的未处理异常处理程序已经为您完成了。这就是他知道自己得到 IOException 的方式。最后,System.IO“更快”的说法是无稽之谈。优化后没有现实世界的差异。
  • 从 root 读取没有问题,在某些系统上写入有问题。 try/catch 语句的原因显然只是作为示例,并不意味着在实践中使用……通常,您可以通过检查适当的对象状态并捕获/记录/忽略所有其他异常来优雅地处理所有错误。此外,不指定路径仅使用当前文件夹,但您可以使用 appdata/temp 文件夹。另外,如果他将其复制到 root 并说他无法读取,那么就有问题了,因为经过身份验证的用户具有 root 的读取权限。 System.IO 更快,但不是很多。
【解决方案3】:
Dim w As New IO.StreamWriter("C:\hitory.txt")*

此代码表示您正在打开一个StreamWriter,您需要先关闭它才能继续。 在您对填充进行任何其他操作之前,请在编码末尾添加w.close()。这有点像打开一部电影并观看它。然后在它仍然打开时将其移动到其他地方。它不会起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-30
    • 2017-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    相关资源
    最近更新 更多