G
Guest
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
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