Hello people. I would like to present my first ever zig based library replace-exe which was inspired by a similar rust library I made use of in zv to handle self update logic. Looking at the original insipiration for this library: mitsuhiko/self-replace, I realized that zig is very well suited for this especially with how easy it is to do FFI.
I really enjoyed the seamless C build experience with zig build system although I needed some help with static linking which was solved thanks to @castholm here : How do I statically/dynamically link to a C exe using build.zig? - #3 by zv2
The original rust implementation on windows makes use of certain tactics in windows that register callbacks in TLS. I am not an expert but here’s a helpful article I found that elaborates on the approach: Running code before main in Rust | Malware Decoded
Basically, for windows, selfDelete requires creation of a separate helper that must detect that it’s a helper exe by detecting its suffix .__selfdelete__.exe and must instead execute the library specific deletion logic rather than the users code. For this, I figured that the above wouldn’t be the right approach given zig’s philosophy of explicit control which is why I switched to a hook based approach requiring users to call @import("replace-exe").init() early on their program to enable this. As you can tell, this is a no-op on linux/unix as these operating systems allow file unlinking while its running but the same isn’t the case for windows for which we need to include a little code as early in main as possible
The applications of this library can be seen in executables wanting to perform self-update or self-uninstall or complex self-uninstall (such as deleting the directory itself in which it’s located). A lot of modern CLI tools like uv, deno, bun come with upgrade/update or self uninstall features and I figured if I am ever writing a CLI tool that needs self update, say fetch release from CI builds & replace the current exe then this would be what I want.
There are some demo executables in the demo folder to play around with (build: zig build -Dcapi -Ddemo) & I would love to hear your thoughts about it.