0

I'm developing a program which could do live-update to modules of our main program.

If the main exe is running, it needs to

1) rename it to temporary name, eg: %productpath%\main.exe -> %productpath%\temp\temp.exe
::MoveFileEx(%productpath%\main.exe, %productpath%\temp\temp.exe, MOVEFILE_REPLACE_EXISTING) --- GetLastError() returns ERROR_SHARING_VIOLATION

2) delete temporary file until reboot
::MoveFileEx(%productpath%\temp\temp.exe, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);

3) copy new downloaded exe to original path %productpath%\main.exe

My questions is why does it fail in the first step, where MoveFileEx() returns ERROR_SHARING_VIOLATION because the exe is running?

My update program has Administrator rights.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
liu jia
  • 47
  • 4
  • This is the Windows way. When a file is executing, its directory entry is locked. See [this article](http://marc.durdin.net/2011/09/why-you-should-not-use-movefileex-with-movefile_delay_until_reboot-2/) for some thoughts. – David Schwartz Jun 23 '15 at 09:24
  • actually, my frustration is I can't rename a running exe by MoveFileEx() – liu jia Jun 23 '15 at 09:41
  • Of course not. The exe file is locked while it is running. You are taking the wrong approach. Once you have downloaded the new exe, you need to either 1) delay-move it over the existing exe file on the next reboot, or 2) have a separate updater app (which I presume is what this code is running in) signal the main exe to exit and wait for that exit to finish, then overwrite the old exe file with the new exe file, and then run the new exe. – Remy Lebeau Jun 23 '15 at 20:13
  • Can you move the file from the command line while the application is running? – Harry Johnston Jun 23 '15 at 22:52

2 Answers2

1

I've figured it out, anyway thanks a lot!

the error ERROR_SHARING_VIOLATION I've met when call MoveFileEx(), is because there's a HANDLE LEAK. Before update the exe/dll file, I've calculated the file MD5 to compare with the value got from Server side, but it missed a CloseHandle() call... so it means it's impossible to rename a running exe in another exe which open that running exe. When I add ClosedHandle(), it could work, the running exe can be renamed to another temp folder without any problem.

liu jia
  • 47
  • 4
0

My questions is why does it fail in the first step, where MoveFileEx() returns ERROR_SHARING_VIOLATION because the exe is running?

Because when windows starts a process, it locks its executable to prevent modification. That way, windows doesn't need to load the entire image into memory, and can page it in on demand.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Usually, however, you can rename and/or move the executable. (I just tried renaming and moving a running executable from the command line, to make sure I wasn't mis-remembering, and it worked perfectly.) – Harry Johnston Jun 23 '15 at 22:50