views:

587

answers:

3

I have a C# application and I want to copy a file to a new location. Some times I need to overwrite an existing file. when this happens I receive a System.IO.IOException. I want to recover from a Sharing violation but how do I determine that IOException was returned because the destination file is in use rather then some other reason? I could look for the "The process cannot access the file because it is being used by another process." message... But I don't like that idea.

+4  A: 

This article explains how to get the exception HRESULT so you can determine the error cause.

Sunny
I was just about to show that :)
Jeremy Reagan
A: 

Look for the explicit error codes that you can deal with, for example:

catch (Exception u) { if (((SocketException)u).ErrorCode == 10035) ...

Take a look here: http://msdn.microsoft.com/en-us/library/ms681391(VS.85).aspx

for error codes, e.g.:

ERROR_SHARING_VIOLATION - 32 - 0x20

ERROR_ACCESS_DENIED = 5 - 0x5

ERROR_FILE_NOT_FOUND - 2 - 0x2

cookre
How will the cast from IOException to SocketException will succeed?
Sunny
just an example... didn't think it would throw anyone off
cookre
+3  A: 

This was the solution I came up with.

private void RobustMoveFile( System.IO.DirectoryInfo destinationDirectory, System.IO.FileInfo sourceFile, Boolean retryMove )
             {
              try
              {
               string DestinationFile = Path.Combine( destinationDirectory.FullName, sourceFile.Name );
               if ( File.Exists( DestinationFile ) )
                sourceFile.Replace( DestinationFile, DestinationFile + "Back", true );
               else
               {
                sourceFile.CopyTo( DestinationFile, true );
                sourceFile.Delete();
               }
              }
              catch ( System.IO.IOException IOEx )
              {
               int HResult = System.Runtime.InteropServices.Marshal.GetHRForException( IOEx );        
               const int SharingViolation = 32;
               if ( ( HResult & 0xFFFF ) == SharingViolation && retryMove )
                RobustMoveFile( destinationDirectory, sourceFile, false );
               throw;
              }
             }
Aaron Fischer
No need to check for destination file existence, as some other process may create/delete it between the check and the replace/CopyTo operations. Just change your logic that you always create the detination file no matter what, and if this fails, recover or retry.
Sunny