0

ERROR:

The process cannot access the file because it is being used by another process. (os error 32)

I'm creating a program in rust and I'm currently working on an 'auto updater'.

I'm trying to have the program write over itself if an update was found and then launch the newer version of itself before exiting memory (Permanently replaced by the newer version). Of course if there is not a newer version then it would continue to function as normal.

My current work around is by having the updater in a "launcher" that does the checks and updates before launching the program. This way it is able to write over the main program since its not currently open in memory. However, it would be a LOT nicer to only have one executable.

Some code:

// Installs the update - writing over the currently installed version.
fs::write(env::current_dir().unwrap().join("program.exe"), program).unwrap();
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • Hi, and welcome to Stack Overflow. Are you on Windows? What file system? – Schwern Apr 01 '22 at 02:59
  • 3
    Superficially I can see the appeal of a single executable updating itself, however if that single executable is botched, bad update, corrupted. etc, then you've just bricked your whole app. I would just call the launcher the app-name, (so people click it), and once the launcher is finished (either silently in the background, or with a big dirty UI), then just get it to execute the real application. – g-radam Apr 01 '22 at 03:04
  • While a program is executing it must have read access to its executable file. This is to get code and also reference data such as strings and numbers. [Windows uses mandatory file locking](https://en.wikipedia.org/wiki/File_locking#In_Microsoft_Windows), meaning if one process has a file open for reading no other process can write to that file. You might be able to do something with [std::os::windows::fs::OpenOptionsExt](https://doc.rust-lang.org/std/os/windows/fs/trait.OpenOptionsExt.html) but there's good reasons why Windows programs have to close before updating. – Schwern Apr 01 '22 at 03:07
  • 1
    @Schwern The reason programs generally close before updating isn't because of file locks, which can be gotten around. It's because updates generally consist of multiple files, and if you use one of those files midupdate its difficult to know if you got the right version or the wrong version. – Gabe Sechan Apr 01 '22 at 03:13
  • @Schwern The OS is currently Windows, but the program is made to be cross-platform. – Austin Hamner Apr 01 '22 at 03:24

1 Answers1

4

A safer way to do this is to have your main app be a symlink to your executable rather than the executable itself. Then you download the new version to a parallel location, switch the link over to the new version, then delete the old version.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • This would work! Thank you, I didn't think about this. Although it is still a workaround and I'm debating whether this or a launcher would be better since my original plan of a single executable has too many holes. – Austin Hamner Apr 01 '22 at 03:44
  • Either can work. The difficulty in a launcher is that sometimes you need to update the launcher as well. But it does provide a nice separation of concerns and gives you two easier to write programs instead of one bigger one. – Gabe Sechan Apr 01 '22 at 04:17
  • You might want to look how other well-known applications do this, for example Mozilla's Firefox. – the busybee Apr 01 '22 at 06:50