Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MoveFileWithProgress抛出“;系统无法将文件移动到其他磁盘驱动器–;为什么?_C#_Windows_Winapi_Pinvoke - Fatal编程技术网

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
);