If you do this on macOS, and your code is codesigned, you are setting yourself for pain. Instead you should replace the file entirely so the file gets a new vnode.
It covers more cases: either a new instance is starting, or it hasn't fully loaded the file yet.
[EDIT: the post has been updated for this point. Thanks so much. https://tritium.legal/blog/update#3.]
[1] Technically speaking I believe this can be solved with transactional NTFS (deprecated but still available as of Windows 11, AFAIK).
Last time I came across it, I worked around it by having a "launcher" that wrote to a temporary path, closed old process, moved and started again. Slight indirection, but seemed to always work and be robust enough, compared to what we initially tried.
Also, it any updating mechanism should be trivially overridable by configuration so that the system package manager can be used, if the application is installed by the system network manager. I hate it when applications manage their own updates... give me a yum repo instead.
1. Have two directories for the app: A and B. One contains the "current" version and one contains (possibly) the "next" version.
2. Have the actual app you start be a separate launcher program that just picks which version to launch.
3. While the app is running, periodically check for updates. If an update is available download and unzip it to the A or B directory that isn't currently in use.
4. Next time the launcher program starts it can say "an updated version is already installed, would you like to use it" (or you can just do that automatically if you - or your user - decide that's the best option). If so it marks the appropriate A/B directory as "current" and launches that one.
Zero delay for users, works on all OSes, works with "always use the latest version" as well as "ask the user to update".
I've never tried this tbf - just an idea.
While it's true that you can't overwrite a running binary on Windows, you can still rename it.
For example, the updater I wrote for AutoPTT downloads the new update to a temporary directory, renames all old files to ${file}.bak, then moves over the files from the temporary folder, and finally runs the new binary while exiting the old one.
What is your preferred way of downloading/installation applications and keeping them up to date?
Personally I love being able to run one command and update everything in one swoop when I have time for it, instead of individually updating things all the time.
AppStores are good enough, as long as they're optional file hosting and censorship service and do not change actual application.
So basically I want no middle-man between developer build and my computer. If developer uploads their application to AppStore and the app gets downloaded to my computer unchanged, that's fine. If some unrelated person pulls sources from github, alters them, builds them and ships them to my computer, that's what I don't like.
> What is your preferred way of downloading/installation applications and keeping them up to date?
Best way is statically linked binary available for direct download (many Golang and Rust apps are distributed this way directly from github). I check for updates when I feel like it, which might not be the best way, so some automatic update reminders are welcome, but by no means are necessary.
Second best way is targzipped directory which I unpack into something like ~/apps/idea and then it keeps itself up to date automatically.
Another thing that I don't like about package managers is that they spill application files all over filesystem. That's also wrong. Files which belong to application must be kept in one place. Ideally separated by chroot-like mechanisms.
It's shocking that people disagree with this. Do you really want to go back to the days where you had to download installers from the internet or copy-paste random 'curl | sudo sh' lines?
Running software shouldn't even have the file permissions to change anything about its own installation.
This morning I updated Firefox through apt, and suddenly the "running" Firefox windows weren't attached to the dock icon, and clicking on the dock icon launched the new FF installation.
Also, Ubuntu's "snap" approach to installing apps is a nightmare that causes no end of problems - unless they ended after I gave up on it. Multiple installs overlapping each other, and I once even had the Firefox snap using a downloads folder in the Skype snap's local data.
Honestly, even with package managers handling all the nitty gritty applications should still be written in such a way that they can quickly sync their state to disk and reload it so that after an app update the app can quickly re-launch with the updated version rather than risking a mix of old and new.
Updating the launcher would still be tricky, but the launcher is tiny, so deleting old versions in a timely manner is not so important.
And yet it's running on windows?!