{"id":51270225,"url":"https://github.com/weezy20/replace-exe","last_synced_at":"2026-06-29T17:33:31.715Z","repository":{"id":322509453,"uuid":"1070954002","full_name":"weezy20/replace-exe","owner":"weezy20","description":"A smol Zig library that lets a running executable replace (or delete) itself.","archived":false,"fork":false,"pushed_at":"2025-11-13T06:59:11.000Z","size":25,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-13T08:34:48.863Z","etag":null,"topics":["zig","zig-library","zig-package"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/weezy20.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-06T16:59:09.000Z","updated_at":"2025-11-13T06:59:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/weezy20/replace-exe","commit_stats":null,"previous_names":["weezy20/replace-exe"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/weezy20/replace-exe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weezy20%2Freplace-exe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weezy20%2Freplace-exe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weezy20%2Freplace-exe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weezy20%2Freplace-exe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/weezy20","download_url":"https://codeload.github.com/weezy20/replace-exe/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weezy20%2Freplace-exe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34937317,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["zig","zig-library","zig-package"],"created_at":"2026-06-29T17:33:28.122Z","updated_at":"2026-06-29T17:33:31.704Z","avatar_url":"https://github.com/weezy20.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# replace-exe\n\nA smol Zig library that lets a running executable replace (or delete) itself.\n\nThis can be used, for instance, in applications implementing a self update feature keeping the current installation path intact.\n\nOnly windows, linux, and unix like systems (macOS, *BSD) are supported.\n\n---\n### Usage\n1. Add the library to your **build.zig.zon**:\n```zsh\nzig fetch --save git+https://github.com/weezy20/replace-exe.git\n```\n\n2. Add it to your **build.zig**:\n```zig\nconst exe = b.addExecutable(.{\n    ...\n});\n\n// Add the replace_exe dependency\nconst libreplace_exe = b.dependency(\"replace_exe\", .{});\nexe.root_module.addImport(\"replace_exe\", libreplace_exe.module(\"replace_exe\"));\n```\n\n3. Call `selfReplace` or `selfDelete` from your code:\n```zig\n// step 1: import\nconst re = @import(\"replace_exe\");\n// step 2: register hook as soon as possible in main(). This is a no-op on non-windows OS:\npub fn main() !void {\n    const allocator = std.heap.page_allocator;\n    // CRITICAL (windows): Call init() BEFORE any application logic.\n    // On Windows, this detects if the process is a cleanup helper and exits immediately.\n    // Any code before this line will run in helper processes too if spawned using selfDelete or selfReplace in windows!\n    re.init(allocator); // or re.init(null) if you want to go with the default ArenaAllocator(std.heap.page_allocator) for `selfDeleteInit()` operations\n    // your logic here..\n}\n// Replace current executable with a new one\ntry re.selfReplace(allocator, \"path/to/new/executable\");\n// Warning: Deletes current executable\ntry re.selfDelete();\n```\n\n\nNote: On windows, if you're deleting the parent folder itself of the current exe itself then you might not want to use `selfDelete` directly but instead provide the current parent dir (or really any dir that you want to prevent from being locked) using `selfDeleteExcludingPath(path: []const u8)` where the function ensures that no temporary exes are put into that path, thereby preventing its deletion for the lifetime of the current running executable.\n\nThe current strategy is to place temporary exes in `%TMP%` or `%TEMP%` \u0026 if that fails due to cross filesystem paths (exe \u0026 temp dir being on different filesystems) we fallback to storing the temp exe helpers in current parent of running exe unless `selfDeleteExcludingPath(p)` is provided in which case, the parent of `p` would be selected \u0026 as a fallback, we would go back to using the same parent dir of current-exe.\n\n\u003e Recommended guidelines:\n\n\u003e - Call these functions at most once each per program execution\n\u003e - (UNSAFE windows) If using both, prefer do selfReplace before selfDelete - This will still not cleanup the helpers properly as the original file would've been moved \u0026 will spawn the new/exe/ which my not have\n\u003e the call to `init()` thereby preventing self-cleanup. It's best to avoid this.\n\u003e - Ideally, make them mutually exclusive in your application logic\n\n---\n\n### Demo\nSome example code is provided in the [demo](demo) folder:\n[demo.zig](demo/demo.zig) is an application that calls `selfReplace` to replace itself with the updated version [demo2.zig](demo/demo2.zig)\n\nBuild the demo applications with:\n```sh\n# Build zig demo exes:\nzig build -Ddemo\n# Build the demo-c executable alongside the above:\nzig build -Ddemo -Dcapi\n```\n\nThen run the first demo exe:\n```sh\n./zig-out/bin/demo delete # self-delete\n./zig-out/bin/demo replace ?\u003c/path/to/new/exe\u003e # self-replace; default path is ./zig-out/bin/demo2\n```\n\nTry out the `demo-c` exe which calls libreplace-exe from C:\n```sh\n./zig-out/bin/demo-c delete\n# verify demo-c is deleted\n```\n\n---\n### FFI via C ABI\nIf you're using it via FFI, the function signatures are defined in [replace_exe.h](include/replace_exe.h) and can be used in your code as the following:\n- `selfReplace` becomes `self_replace(const char* path)`\n- `selfDelete` becomes `self_delete()`\n- `selfDeleteExcludingPath` becomes `self_delete_excluding_path(const char* path)`\n- `init(?std.mem.Allocator)` becomes `init()`\n\nSee [c_api.zig](c_api.zig) for definitions. \nBuilding the library as a shared object or static library for use with C/C++:\n\nBuilding:\n```sh\n# This builds a .so shared library like libreplace-exe.so that you can link against\nzig build -Dcapi -Dso -Doptimization=ReleaseFast\n# Or if you prefer a static library:\nzig build -Dcapi -Doptimization=ReleaseFast\n```\nExample usage in C (using dynamic library): See [demo.c](demo/demo.c)\n\n1. Build your C app using either of the generated libraries:\n```sh\ngcc demo/demo.c -Izig-out/include -Lzig-out/lib -lreplace-exe -o test\n```\n2. Run the C demo:\n```sh\nLD_LIBRARY_PATH=zig-out/lib ./test /path/to/new/executable\n```\n3. Run again to verify replacement:\n```sh\nLD_LIBRARY_PATH=zig-out/lib ./test\n```\n\nOr if you prefer go (using `cgo`): See [demo/main.go](demo/main.go) for an example.\n1. Build your Go app linking `libreplace-exe.a` or `libreplace-exe.so`:\n```sh\ngo build -o demo-go demo/main.go\n```\n2. Run the Go demo:\n```sh\n./demo-go replace /path/to/new/executable\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweezy20%2Freplace-exe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fweezy20%2Freplace-exe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweezy20%2Freplace-exe/lists"}