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