C# MoveFileWithProgress抛出“;系统无法将文件移动到其他磁盘驱动器–;为什么?
我有: 并称之为:C# MoveFileWithProgress抛出“;系统无法将文件移动到其他磁盘驱动器–;为什么?,c#,windows,winapi,pinvoke,C#,Windows,Winapi,Pinvoke,我有: 并称之为: [SuppressUnmanagedCodeSecurity] [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern bool MoveFileWithProgress( string lpExistingFileName, string lpNewFileName, CopyProgressRoutine lpProgressRoutine
[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
}
其中:options
是MoveFileOptions.MOVEFILE\u COPY\u允许的
在硬盘中移动时,它工作正常。但是当我尝试移动到闪存驱动器时,我得到:系统无法将文件移动到其他磁盘驱动器
为什么?从本页上看,它说:
不能在使用rename命令重命名文件的同时将其移动到其他磁盘驱动器
请在移动文件之前尝试重命名它。您是否正在移动目录 根据(增加的重点): 移动文件时,lpNewFileName可以位于不同的文件系统或卷上。如果lpNewFileName位于另一个驱动器上,则必须在dwFlags中设置MOVEFILE\u COPY\u ALLOWED标志 移动目录时,lpExistingFileName和lpNewFileName必须位于同一驱动器上
您的
DllImport
不正确。您的函数只有4个参数,但有5个。大概发生的情况是,MOVEFILE\u COPY\u ALLOWED
被传递到lpData
并被忽略。dwFlags
参数就是堆栈上发生的任何事情
修复p/invoke可能会解决问题。而且,dwFlags
应该是无符号的
if (!MoveFileWithProgress(source.FullName, destination.FullName, cpr, (int)options)) {
throw new IOException(new Win32Exception().Message);
}
正确后,您需要决定传递给
lpData
的内容。因为您目前似乎没有使用它,所以这并不重要,而且IntPtr.Zero
似乎是一个明显的选择。我们可以看到您对MoveFileWithProgress的实际调用吗?@M.Babcock如果(!MoveFileWithProgress(source.FullName,destination.FullName,cpr,(int)选项)){throw new IOException(new Win32Exception().Message);}
请更新您的答案,而不是将代码作为注释发布。我正在将其从@“c:\users\Me\t.txt”
重命名为@“f:\t.txt”
。似乎不是真正的更名。我该怎么做才能有所不同呢?@ispiro无法在没有看到更多代码的情况下立即判断。如果闪存驱动器出现问题,则可能是一般性错误。该文件是否可能已经存在于闪存驱动器上?如果您只是尝试对相同的两个文件使用普通File.Copy(),会发生什么情况?当移动到CD时,我会遇到相同的错误。(并且File.Move()
在那里也可以正常工作。)显示的MoveFileWithProgress调用的签名与您使用的不同。有些东西需要尝试。@LarsTech:你是对的,上面的代码作为dwFlags
之前的参数缺少了IntPtr lpData
——很可能这就是问题的根源。尽管你认为他会使用来自的相同调用。@LarsTech嗯,也许Q中的代码不是真正的代码,只是一个复制/粘贴错误。完全删除一个参数似乎会让人惊讶。谢谢。就这样。我认为,当说一个参数是可选的时,这就像C#中的重载一样——可以完全忽略一个参数。这似乎只是意味着可以传递一个IntPtr.Zero
(在本例中)。是的,像C#中的可选参数始终是一个语言构造,但Windows的本机语言是C,没有可选参数或重载。因此,可选的win api参数是不变的指针,NULL
表示您忽略了该参数。
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool MoveFileWithProgress(
string lpExistingFileName,
string lpNewFileName,
CopyProgressRoutine lpProgressRoutine,
IntPtr lpData,
uint dwFlags
);