【问题标题】:MoveFileEx() returns ERROR_SHARING_VIOLATIONMoveFileEx() 返回 ERROR_SHARING_VIOLATION
【发布时间】:2015-06-23 09:15:22
【问题描述】:

我正在开发一个可以实时更新我们主程序的模块的程序。

如果主exe正在运行,则需要

1) 将其重命名为临时名称,例如:%productpath%\main.exe -> %productpath%\temp\temp.exe
::MoveFileEx(%productpath%\main.exe, %productpath%\temp\temp.exe, MOVEFILE_REPLACE_EXISTING) --- GetLastError() 返回ERROR_SHARING_VIOLATION

2) 删除临时文件直到重启
::MoveFileEx(%productpath%\temp\temp.exe, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);

3) 将新下载的exe复制到原路径%productpath%\main.exe

我的问题是为什么它在第一步失败,MoveFileEx() 返回ERROR_SHARING_VIOLATION 因为 exe 正在运行?

我的更新程序具有管理员权限。

【问题讨论】:

  • 这是 Windows 方式。当一个文件正在执行时,它的目录条目被锁定。请参阅this article 了解一些想法。
  • 实际上,我的沮丧是我无法通过 MoveFileEx() 重命名正在运行的 exe
  • 当然不是。 exe文件在运行时被锁定。你采取了错误的方法。下载新的 exe 后,您需要 1) 在下次重新启动时将其延迟移动到现有的 exe 文件上,或者 2) 有一个单独的更新程序应用程序(我认为这是运行此代码的内容)发出信号main exe 退出并等待该退出完成,然后用新的 exe 文件覆盖旧的 exe 文件,然后运行新的 exe。
  • 你可以在应用程序运行时从命令行移动文件吗?

标签: windows winapi movefileex


【解决方案1】:

我已经弄明白了,还是非常感谢!

我在调用 MoveFileEx() 时遇到的错误 ERROR_SHARING_VIOLATION 是因为存在 HANDLE LEAK。在更新 exe/dll 文件之前,我已经计算了文件 MD5 以与从服务器端获得的值进行比较,但它错过了 CloseHandle() 调用......所以这意味着不可能在另一个 exe 中重命名正在运行的 exe打开那个正在运行的exe。 当我添加 ClosedHandle() 时,它可以工作,正在运行的 exe 可以重命名到另一个临时文件夹,没有任何问题。

【讨论】:

    【解决方案2】:

    我的问题是为什么它在第一步中失败,因为 exe 正在运行,MoveFileEx() 返回 ERROR_SHARING_VIOLATION?

    因为当 windows 启动一个进程时,它会锁定其可执行文件以防止修改。这样,windows 就不需要将整个图像加载到内存中,并且可以按需分页。

    【讨论】:

    • 不过,通常您可以重命名和/或移动可执行文件。 (我只是尝试从命令行重命名和移动一个正在运行的可执行文件,以确保我没有记错,而且效果很好。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多