title: How do I determine the HResult for a System.IO.IOException?
body: <p>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? </p>
  
  <hr>
  
  <p>Here's the situation:<br>
  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 <a href="https://stackoverflow.com/questions/897796/how-do-i-open-an-already-opened-file-with-a-net-streamreader">this guidance</a>, because I don't care if the file is open for writing at the time I read it.  </p>
  
  <p>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 <a href="http://msdn.microsoft.com/en-us/library/ms681382.aspx" rel="noreferrer">error 33</a>, or I think HResult 0x80070021.  [<strong>EDIT</strong>: I believe this can be returned when another process calls <a href="http://msdn.microsoft.com/en-us/library/aa365203.aspx" rel="noreferrer">LockFileEx</a> to lock a byte range within a file.]</p>
  
  <p>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.</p>
  
  <p>How can I distinguish an IOException for this reason, from others? I can think of these ways:</p>
  
  <ul>
  <li>private reflection - don't wanna do that.  Perf will stink. </li>
  <li>call Exception.ToString() and parse the string. Feels hacky. Won't work in i18n versions. </li>
  </ul>
  
  <p>I don't like these options.  Isn't there a better, cleaner way?</p>
  
  <hr>
  
  <p>I just searched around and found <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.gethrforexception.aspx" rel="noreferrer">System.Runtime.InteropServices.Marshal.GetHRForException</a>.  Will that return a uint like 0x80070021?</p>