ispiro
ispiro

Reputation: 27743

MoveFileWithProgress throws "The system cannot move the file to a different disk drive" – why?

I have:

[SuppressUnmanagedCodeSecurity]
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool MoveFileWithProgress(
    string lpExistingFileName, string lpNewFileName,
    CopyProgressRoutine lpProgressRoutine,
    int dwFlags);

public enum MoveFileOptions 
{
    MOVEFILE_COPY_ALLOWED = 0x2
}

And calling it with:

if (!MoveFileWithProgress(source.FullName, destination.FullName, cpr, (int)options)) {
  throw new IOException(new Win32Exception().Message);
}

Where: options is MoveFileOptions.MOVEFILE_COPY_ALLOWED

It works fine when moving in the hard drive. But when I try moving to a Flash-drive, I get: The system cannot move the file to a different disk drive.

Why?

Upvotes: 2

Views: 2009

Answers (3)

David Heffernan
David Heffernan

Reputation: 613572

Your DllImport is incorrect. Your function has only 4 parameters, but the real function has 5. Presumably what is happening is that MOVEFILE_COPY_ALLOWED is being passed to lpData and is ignored. The dwFlags parameter is just whatever happens to be sitting on the stack.

Fixing your p/invoke will probably solve the problem. Also, dwFlags should be unsigned.

[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool MoveFileWithProgress(
    string lpExistingFileName,
    string lpNewFileName,
    CopyProgressRoutine lpProgressRoutine,
    IntPtr lpData,
    uint dwFlags
);

With this correct you need to decide what to pass to lpData. Since you appear not to be using it at the moment, it doesn't really matter and IntPtr.Zero seems the obvious choice.

Upvotes: 3

bobbymcr
bobbymcr

Reputation: 24177

Are you perhaps moving a directory?

According to the documentation for MoveFileWithProgress at MSDN (emphasis added):

When moving a file, lpNewFileName can be on a different file system or volume. If lpNewFileName is on another drive, you must set the MOVEFILE_COPY_ALLOWED flag in dwFlags.

When moving a directory, lpExistingFileName and lpNewFileName must be on the same drive.

Upvotes: 2

LarsTech
LarsTech

Reputation: 81675

From this Microsoft | Technet page, it says:

The file cannot be moved to a different disk drive at the same time you rename it using the Rename command.

Try renaming the file before moving it.

Upvotes: 3

Related Questions