Windows API MoveFile()无法运行exe

问题描述 投票:1回答:1

这是一个简单的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仍然存在,就像CopyFile()那样。

据我所知,在Windows中,当exe运行时我可以重命名,移动它,但不删除它,MoveFile()表现为CopyFile()DeleteFile()的组合

并且还可以从Microsoft doc MoveFileEx看到这一点。

BOOL WINAPI MoveFileEx(
  _In_     LPCTSTR lpExistingFileName,
  _In_opt_ LPCTSTR lpNewFileName,
  _In_     DWORD   dwFlags
);

dwFlags有一个选项MOVEFILE_COPY_ALLOWED

该文件将被移动到另一个卷,该函数使用CopyFile和DeleteFile函数模拟移动。如果文件已成功复制到其他卷并且无法删除原始文件,则该函数将成功保留源文件。该值不能与MOVEFILE_DELAY_UNTIL_REBOOT一起使用。

进一步证实了我的猜测,我用MoveFileEx()用选项MOVEFILE_REPLACE_EXISTING测试,重新编译程序,运行它,现在MoveFileEx()刚刚返回失败,甚至没有生成dst.exe。

但我肯定可以在运行时剪切和粘贴那个exe,MoveFileEx()应该这样做,为什么???

如果他们不能,我该怎么做就像剪切和粘贴一样。

c windows winapi
1个回答
5
投票

如果目标目标位于同一卷上,则MoveFile只会更新相应的目录条目。文件的MFT记录未更改,其索引保持不变,其内容未被触及。因为文件根本不受影响,所以即使文件正在使用,你也可以在相同的目录(即重命名)或相同的卷内移动它(注意:这对于正在执行的文件是正确的;通常,这是真的仅当文件使用FILE_SHARE_DELETE打开时)。

如果目标目录位于另一个卷上,则系统需要复制它(如果文件以独占模式打开将失败)并在旧卷上将其删除(如果文件正在使用,将无条件地失败)。

剪切和粘贴在相同的卷内正常工作,而不是在不同的卷上。原因是文件剪贴板操作使用与文本操作不同的技术。

当您选择文本并按Ctrl-X时,文本字符串将移动到已分配的全局内存块,并将该块传递给Windows。该程序不再拥有它。该文本实际上位于Windows剪贴板中,您可以根据需要多次粘贴它。

当您在文件上按Ctrl-X时,它不会移动到剪贴板。剪贴板将接收文件描述符,其中包含有关文件和请求的操作的信息(此技术称为延迟呈现)。按Ctrl-C时,剪贴板将只询问对象所有者(即Windows资源管理器)以执行请求的操作。 Explorer将使用完全相同的MoveFile执行它。

请注意,您只能粘贴一个剪切文件,因为第一个Ctrl-C将使剪贴板中的描述符无效。复制的文件可以粘贴多次。

© www.soinside.com 2019 - 2024. All rights reserved.