Home All Groups Group Topic Archive Search About

Framework v2.0 - File.Copy Bug - Could someone confirm this?

Author
10 Feb 2006 8:36 PM
Simon Murrell
Hello

I recently copied some code over from a project in .NET Framework v1.1
to v2.0. And found that when I copied a file and then tried to delete it
afterwards,
an exception ocurred saying that the file was being used by another process.
I then used the .NET Reflector tool and went into the mscorlib.dll into the
InternalCopy method which is used by the File.Copy method. The code is below.

internal static string InternalCopy(string sourceFileName, string
destFileName, bool overwrite)
{
      if ((sourceFileName == null) || (destFileName == null))
      {
            throw new ArgumentNullException((sourceFileName == null) ?
"sourceFileName" : "destFileName",
Environment.GetResourceString("ArgumentNull_FileName"));
      }
      if ((sourceFileName.Length == 0) || (destFileName.Length == 0))
      {
            throw new
ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"),
(sourceFileName.Length == 0) ? "sourceFileName" : "destFileName");
      }
      string text1 = Path.GetFullPathInternal(sourceFileName);
      new FileIOPermission(FileIOPermissionAccess.Read, new string[] { text1
}, false, false).Demand();
      string text2 = Path.GetFullPathInternal(destFileName);
      new FileIOPermission(FileIOPermissionAccess.Write, new string[] {
text2 }, false, false).Demand();
      if (!Win32Native.CopyFile(text1, text2, !overwrite))
      {
            int num1 = Marshal.GetLastWin32Error();
            string text3 = destFileName;
            if (num1 != 80)
            {
                  using (SafeFileHandle handle1 =
Win32Native.UnsafeCreateFile(text1, -2147483648, FileShare.Read, null,
FileMode.Open, 0, IntPtr.Zero))
                  {
                        if (handle1.IsInvalid)
                        {
                              text3 = sourceFileName;
                        }
                  }
                  if ((num1 == 5) && Directory.InternalExists(text2))
                  {
                        throw new
IOException(string.Format(CultureInfo.CurrentCulture,
Environment.GetResourceString("Arg_FileIsDirectory_Name"), new object[] {
destFileName }), 5, text2);
                  }
            }
            __Error.WinIOError(num1, text3);
      }
      return text2;
}

This section

                  using (SafeFileHandle handle1 =
Win32Native.UnsafeCreateFile(text1, -2147483648, FileShare.Read, null,
FileMode.Open, 0, IntPtr.Zero))
                  {
                        if (handle1.IsInvalid)
                        {
                              text3 = sourceFileName;
                        }
                  }

seems to be keeping keeping the SafeFileHandle's base.handle property active
once it has initialized the SafeFileHandle class. I changed the code to the
following

using (SafeFileHandle handle1 = UnsafeCreateFile(text1, -2147483648,
FileShare.Read, null, FileMode.Open, 0, IntPtr.Zero))
                    {
                        //if (handle1.IsInvalid)
                        //{
                        //    text3 = sourceFileName;
                        //}
                        handle1.ReleaseTheHandle();
                    }

My application could then delete the file afterwards. The
handle1.ReleaseTheHandle
basically calls the CloseHandle Win32 API call on the base.handle property of
the SafeFileHandle class. Could someone check this for me.

Regards,
Simon

Author
11 Feb 2006 9:48 AM
Vadym Stetsyak
Hello, Simon!

SM> I recently copied some code over from a project in .NET Framework v1.1
SM> to v2.0. And found that when I copied a file and then tried to delete
SM> it afterwards,
SM> an exception ocurred saying that the file was being used by another
SM> process. I then used the .NET Reflector tool and went into the
SM> mscorlib.dll into the InternalCopy method which is used by the
SM> File.Copy method. The code is below.

There no 'temp.txt' file in the D:, that is CreateFile will be called.
File.Copy(@"c:\temp.txt", @"d:\temp.txt");

File.Delete(@"d:\temp.txt");
Everythinh is okay file is deleted

Code above works fine on my machine.

Can you post the  code where you're copying and deleting file.
--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com
Author
11 Feb 2006 10:47 AM
Simon Murrell
Hello Vadym

Copy more than 1 file, like 20+. I started getting it after the fifth file.
When I changed the code to release the handle, it stopped locking the
file and I could then delete it. If I didn't change the code, it kept on
locking
the file.

Regards,
Simon

Show quote
"Vadym Stetsyak" wrote:

> Hello, Simon!
>
>  SM> I recently copied some code over from a project in .NET Framework v1.1
>  SM> to v2.0. And found that when I copied a file and then tried to delete
>  SM> it afterwards,
>  SM> an exception ocurred saying that the file was being used by another
>  SM> process. I then used the .NET Reflector tool and went into the
>  SM> mscorlib.dll into the InternalCopy method which is used by the
>  SM> File.Copy method. The code is below.
>
> There no 'temp.txt' file in the D:, that is CreateFile will be called.
> File.Copy(@"c:\temp.txt", @"d:\temp.txt");
>
> File.Delete(@"d:\temp.txt");
> Everythinh is okay file is deleted
>
> Code above works fine on my machine.
>
> Can you post the  code where you're copying and deleting file.
> --
> Regards, Vadym Stetsyak
> www: http://vadmyst.blogspot
Author
11 Feb 2006 11:13 AM
Vadym Stetsyak
Hello, Simon!

Strange, but I'm not getting the exception
Here is my sample code

string file1;
string file2;
FileStream fs;
for (int index = 0; index < 200; index++)
{
fs = File.Create(file1 = string.Format(@"c:\temp{0}.txt", index.ToString()));
fs.Close();
File.WriteAllText(file1, "Contents - " + file1);

File.Copy(file1,
    file2 = string.Format(@"d:\temp{0}.txt", index.ToString()));

File.Delete(file2);
File.Delete(file1);
}
--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com
Author
11 Feb 2006 11:11 AM
Simon Murrell
Hello Vadym

The app which I wrote it in is a Windows Service app which performs the
file copying and deleting together in a thread. I wrote a separate app doing
it where it does the copying in the main GUI thread and it works perfectly.
Maybe it has something to do with a windows service and running it in a
separate thread from the main service thread. From what I could see is that
it definately was keeping a lock on the file(s). Then I added the segment of
code to release the handle and it worked perfectly. Then I commented out the
code to release the handle and it threw the exception again. Weird!!!! See
what you can find???

Regards,
Simon

Show quote
"Vadym Stetsyak" wrote:

> Hello, Simon!
>
>  SM> I recently copied some code over from a project in .NET Framework v1.1
>  SM> to v2.0. And found that when I copied a file and then tried to delete
>  SM> it afterwards,
>  SM> an exception ocurred saying that the file was being used by another
>  SM> process. I then used the .NET Reflector tool and went into the
>  SM> mscorlib.dll into the InternalCopy method which is used by the
>  SM> File.Copy method. The code is below.
>
> There no 'temp.txt' file in the D:, that is CreateFile will be called.
> File.Copy(@"c:\temp.txt", @"d:\temp.txt");
>
> File.Delete(@"d:\temp.txt");
> Everythinh is okay file is deleted
>
> Code above works fine on my machine.
>
> Can you post the  code where you're copying and deleting file.
> --
> Regards, Vadym Stetsyak
> www: http://vadmyst.blogspot
Author
11 Feb 2006 11:52 AM
Vadym Stetsyak
Hello, Simon!

I've wrote service app, put the sample, that i've posted above ( with 200 copies and deletes ),
into separate thread, and still get nothing.

Are you doing any I/O from other threads with these files?

--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com

AddThis Social Bookmark Button