这是一个简单的C程序,用于说明:
#include <windows.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
//MoveFile(argv[0], "dst.exe");
getchar();
return 0;
}
从上面的代码制作一个test.exe。
现在执行test.exe,由于getchar(),test.exe挂起,然后我可以自由剪切并粘贴这个exe。
但是,当我取消注释MoveFile(argv[0], "dst.exe");
时,我希望它可以移动到dst.exe,结果是有一个dst.exe,而program.exe仍然存在,就像{{1}一样确实。
据我所知,在Windows中,当exe运行时,我可以重命名,移动它,但不删除它,CopyFile()
表现为MoveFile()
和CopyFile()
的组合
另请参阅Microsoft doc MoveFileEx。
DeleteFile()
dwFlags有一个选项BOOL WINAPI MoveFileEx(
_In_ LPCTSTR lpExistingFileName,
_In_opt_ LPCTSTR lpNewFileName,
_In_ DWORD dwFlags
);
该文件将被移动到另一个卷,该函数使用CopyFile和DeleteFile函数模拟移动。 如果文件已成功复制到其他卷并且无法删除原始文件,则该函数将成功保留源文件。 该值不能与MOVEFILE_DELAY_UNTIL_REBOOT一起使用。
进一步确认我的猜测,我使用MOVEFILE_COPY_ALLOWED
选项MoveFileEx()
进行测试,重新编译程序,运行它,现在MOVEFILE_REPLACE_EXISTING
刚刚返回失败,甚至没有生成dst.exe。
但是我可以肯定剪切并粘贴运行时的那个exe,MoveFileEx()
应该这样做,为什么???
如果他们不能,我该怎么做就像剪切和粘贴一样。
答案 0 :(得分:5)
如果目标目标位于同一卷上,则MoveFile只会更新相应的目录条目。文件的MFT记录未更改,其索引保持不变,其内容未被触及。因为文件根本不受影响,所以即使文件正在使用,你也可以在相同的目录(即重命名)或相同的卷内移动它(注意:这对于正在执行的文件是正确的;通常,这是真的仅当文件使用FILE_SHARE_DELETE打开时。
如果目标目录位于另一个卷上,则系统需要复制它(如果文件以独占模式打开则会失败)并在旧卷上删除它(如果文件正在使用,将无条件地失败)。 / p>
剪切和粘贴在相同的卷中正常工作,而在不同的卷上不能正常工作。原因是文件剪贴板操作使用的技术与文本操作不同。
当您选择文本并按Ctrl-X时,文本字符串将移动到已分配的全局内存块,并且该块将传递给Windows。该程序不再拥有它。该文本实际上位于Windows剪贴板中,您可以根据需要多次粘贴它。
当您在文件上按Ctrl-X时,它不会移动到剪贴板。剪贴板将接收文件描述符,其中包含有关文件和请求的操作的信息(此技术称为延迟呈现)。按Ctrl-C时,剪贴板将只询问对象所有者(即Windows资源管理器)以执行请求的操作。资源管理器将使用完全相同的MoveFile执行它。
请注意,您只能粘贴一个剪切文件,因为第一个Ctrl-C会使剪贴板中的描述符无效。复制的文件可以多次粘贴。