inst_prg.bat installs an already-downloaded archive or installer into %PRGS%.
The usual workflow is:
dwl codex
inst_prg codexThe default senv.doskey also exposes these aliases:
inst codex
install codex
in codexdwl.bat stores files in %PRGS%\setup.
inst_prg.bat finds the matching file, copies it locally if needed, extracts or installs it, runs optional hooks, and creates a current junction by default.
inst_prg [program] [pattern-or-latest] [symlink-name]Examples:
inst_prg codex
inst_prg codex latest
inst_prg codex codex-rust-v0.141.0-x86_64-pc-windows-msvc.zip
inst_prg codex latest codex0141Arguments:
program: name or alias frombin\prgs.list.pattern-or-latest: explicit file pattern, version fragment, orlatest.symlink-name: optional junction name. Defaults tocurrent, unlessinst_prg.batderives a versioned name for known families.
For normal program names, inst_prg.bat calls:
select_prg.bat <program> inst_prgThat resolves:
prg_id: install id without trailings.prg_pattern: archive pattern frombin\prgs.list.prgs_folder: computed as%prg_id%s.
For Codex:
Codex/cdx~#~codexs~codex-rust-v*-x86_64-pc-windows-msvc.zip~global
This resolves to:
prg_id=codexprgs_folder=codexsprg_pattern=codex-rust-v*-x86_64-pc-windows-msvc.zip
If the first argument contains *, inst_prg.bat enters list mode and searches for that pattern directly.
inst_prg.bat searches for the selected archive in this order:
%PRGS%\setup%USERPROFILE%\Downloads%setupsdir%, when configured by the active profile%USERPROFILE%\senv_setups\setups, when it exists
When a match is found outside %PRGS%\setup, it is copied into %PRGS%\setup before installation.
When latest is used, the installer asks bin\dir_by_date.ps1 for the newest matching file by creation time across the searched locations.
When no match is found for a Python zip pattern, inst_prg.bat falls back to pythons.install.bat.
The pattern comes from prgs.list, but a second argument can narrow it.
Given:
codex-rust-v*-x86_64-pc-windows-msvc.zip
These calls result in these searches:
inst_prg codexUses the declared pattern and selects the latest matching file.
inst_prg codex 0.141.0Injects the version fragment into the first *, producing a search like:
codex-rust-v*0.141.0*x86_64-pc-windows-msvc.zip
inst_prg codex "codex-rust-v0.141.0-x86_64-pc-windows-msvc.zip"Uses the explicit pattern as-is.
Patterns can contain alternatives separated by /. drawio uses this to allow both the .zip and the older -no-installer.exe asset shape.
After a single file is selected:
fnameis set to the selected archive filename.prg_folderis set to the archive basename, using%%~ni.%PRGS%\%prgs_folder%is created if missing.- The archive is copied into
%PRGS%\%prgs_folder%. - A custom install hook may run.
- Otherwise,
pzxx.batextracts the archive with 7-Zip. .tar.xzarchives get a second extraction pass for the inner.tar.- A post-install hook may run.
check_prg_symlink.batcreates or updates the symlink, usually%PRGS%\%prgs_folder%\current. If that name is a real directory instead of a junction (previous manual installation), it is kept aside ascurrent.oldfirst.- An alias hook may run.
For Codex, a downloaded file like:
codex-rust-v0.141.0-x86_64-pc-windows-msvc.zip
installs into:
%PRGS%\codexs\codex-rust-v0.141.0-x86_64-pc-windows-msvc
and then:
%PRGS%\codexs\current
points to that folder.
Create installs\<prgs_folder>.install.bat when default extraction is not enough.
The hook is called before default extraction:
call "%install_dir%\%prgs_folder%.install.bat" "%sln%"Use a custom install hook when:
- The downloaded file is a standalone
.exethat should be copied into a versioned folder. - The archive layout needs reshaping before symlink creation.
- The program has a non-archive installer flow.
Examples in this repo:
tailwindcsss.install.bat: copies the downloaded executable into a versioned directory under several executable names and adds a local alias.riffs.install.batandmoars.install.bat: handle standalone executables.pythons.install.bat: handles Python-specific installation.vscodes.install.bat: handles VS Code-specific install/update behavior.
If no custom install hook exists, inst_prg.bat extracts with pzxx.bat.
Create installs\<prgs_folder>.post.bat when default extraction works, but the installed tree needs a small adjustment.
The hook is called after extraction and before symlink creation:
call "%install_dir%\%prgs_folder%.post.bat"Use a post hook when:
- A file must be copied or renamed after extraction.
- Settings directories must be created.
- App configuration must be patched.
- A tool needs extra local files before
currentis created.
Examples:
npps.post.bat: creates a Notepad++ settings directory and updates Git editor configuration.peazips.post.bat: adds a missingres\7zjunction.terminals.post.bat: delegates to a PowerShell wrapper for Windows Terminal settings.codexs.post.bat: copiescodex-x86_64-pc-windows-msvc.exetocodex.exe.
Codex is a post-install case because the zip extraction is normal, but the executable name is platform-specific. The installed command should be stable:
codex.exe
Create installs\<prgs_folder>.sln.bat when the default symlink target or symlink name needs adjustment.
check_prg_symlink.bat calls the hook and uses its output as the symlink name.
Examples:
javas.sln.batmavens.sln.batnodes.sln.batpythons.sln.batwildflys.sln.bat
inst_prg.bat also has built-in symlink names for common families:
- Node archives become names like
node22. - Python archives become names like
python3. - JDK archives become names like
jdk21. - Maven archives become names like
mvn3.9.9. - WildFly archives become names like
wildfly35.
If no hook or built-in rule applies, the symlink name is current.
Create installs\<prgs_folder>.alias.bat when installation should add or refresh command aliases.
The hook runs after symlink creation.
Examples:
drawios.alias.batpostmans.alias.bat
Alias hooks commonly edit %HOME%\bin\senv.local.doskey and reload aliases with DOSKEY /MACROFILE.
check_prg_symlink.bat checks whether the extracted folder contains a single subdirectory. If it does, the junction targets that nested folder instead of the outer extraction folder.
This handles archives that unpack as:
tool-version\tool-version\tool.exe
instead of:
tool-version\tool.exe
Default extraction creates a .tar folder first. inst_prg.bat then enters that folder, extracts the inner .tar, and removes the .tar file.
This is used by entries such as msys2.
Default extraction expects an archive. For a single .exe, either:
- Repackage it during
dwl.bat, asjqdoes. - Add a custom
.install.bat, astailwindcsss,riffs, andmoarsdo.
Use a post hook when the installed executable should have a stable name.
Codex downloads and extracts:
codex-x86_64-pc-windows-msvc.exe
installs\codexs.post.bat creates:
codex.exe
The original executable remains in place.
Use / in the prgs.list pattern when a program has multiple accepted asset names.
Example:
draw.io-*-windows.zip/draw.io-*-windows-no-installer.exe
inst_prg.bat checks each pattern in order.
The command you type may resolve to %HOME%\bin, not this repository.
Check with:
where inst_prg
where dwlsetup.bat copies bin\* into %HOME%\bin. If you change bin\dwl.bat, bin\prgs.list, or install hooks while developing locally, make sure the active copy is updated before testing from a normal shell.