如何确定产生HResult的System.IO.IOException?System、HResult、IOException、IO

2023-09-02 01:40:05 作者:无法言表的伤

该System.Exception.HResult财产受到保护。我怎么能偷看例外内,得到的HResult而不是诉诸反射或其它丑陋黑客?

下面的情况: 我想写一个备份工具,打开和系统上读取文件。 我打开与FileAccess.Read和FileShare.ReadWrite文件,根据this指导,因为我不关心,如果该文件是开放的,在写我读它的时候。

在某些情况下,当一个文件,我看是打开另一个应用程序时,System.IO.FileStream.Read()方法抛出一个System.IO.IOException,该进程无法访问文件,因为另一个进程已锁定该文件的一个部。这是错误33 ,或者我认为HResult的0x80070021。 [修改:我相信,当另一个进程调用这个可以返回 LockFileEx 要在一个文件中锁定一个字节范围。]

我想停下来时,我得到这个错误重试。我认为这是采取适当的行动在这里。如果锁定过程中迅速释放字节范围锁,那么我就可以继续读取文件。

我如何能分辨一个IOException因为这个原因,从其他人呢?我能想到的这些方式:

在私人反思 - 不想这样做。 PERF就会发臭。 在调用Exception.ToString()和解析字符串。感觉哈克。将国际化的版本无法正常工作。

我不喜欢这些选项。是不是还有更好的,更清洁的方式?

我只是搜查了一圈,发现System.Runtime.InteropServices.Marshal.GetHRForException.会返回一个UINT像0x80070021?

解决方案 C 中的Stream相关

您可以使用Marshal.GetHRForException找回HRESULT:

  INT HR = Marshal.GetHRForException(前);
 

参考

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.gethrforexception.aspx

The System.Exception.HResult property is protected. How can I peek inside an exception and get the HResult without resorting to reflection or other ugly hacks?

Here's the situation: I want to write a backup tool, which opens and reads files on a system. I open the file with FileAccess.Read and FileShare.ReadWrite, according to this guidance, because I don't care if the file is open for writing at the time I read it.

In some cases, when a file I am reading is open by another app, the System.IO.FileStream.Read() method throws a System.IO.IOException, "The process cannot access the file because another process has locked a portion of the file". This is error 33, or I think HResult 0x80070021. [EDIT: I believe this can be returned when another process calls LockFileEx to lock a byte range within a file.]

I'd like to pause and retry when I get this error. I think this is the appropriate action to take here. If the locking process releases the byte-range lock quickly, then I can proceed reading the file.

How can I distinguish an IOException for this reason, from others? I can think of these ways:

private reflection - don't wanna do that. Perf will stink. call Exception.ToString() and parse the string. Feels hacky. Won't work in i18n versions.

I don't like these options. Isn't there a better, cleaner way?

I just searched around and found System.Runtime.InteropServices.Marshal.GetHRForException. Will that return a uint like 0x80070021?

解决方案

You can use Marshal.GetHRForException to get back the HResult:

int hr = Marshal.GetHRForException( ex );

Reference

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.gethrforexception.aspx