venvctl
Control your Python virtual environments on Windows.
One on/off in PowerShell, CMD and Git Bash. Find, unlock, repair and prune venvs from a single binary.
venvctl creates environments with uv or venv and manages them afterwards. It does not install packages or Python versions.
Not related to the venvctl package on PyPI.
PS D:\code\api> venvctl nuke old-api
1 process holds files in C:\Users\you\AppData\Local\venvctl\envs\old-api:
PID NAME SPAWNED BY OPEN FILES
30728 Python powershell.exe 1: python.exe
terminate 1 process? [y/N]
Deleting a venv on Windows often fails with Access is denied (os error 5) and no explanation. venvctl identifies the process holding the files and what launched it, asks before stopping it, and refuses when the holder is an editor or a shell. The folder is renamed before it is deleted, so a failed delete never leaves a half-removed environment behind.
Features
| One activation command | venvctl on and venvctl off behave the same in PowerShell 5.1 and 7, CMD and Git Bash. Activate.ps1 is never run; PATH is saved once and restored exactly. |
Auto-activate on cd |
Opt-in. Only project roots you have approved with venvctl allow activate, because activating a venv runs its code. About 0.4 ms per prompt when nothing changed. |
| Safe deletion | nuke and prune name the locking processes via the Windows Restart Manager, protect editors and shells, and delete rename-first. PowerToys File Locksmith is used as a read-only fallback when installed. |
| Discovery | scan walks every fixed drive for pyvenv.cfg; list shows size, Python version, last use and broken or missing environments; prune removes them by age, size or status. |
| Repair after a move | repair rewrites the absolute paths that pip and uv launchers embed, so a renamed project folder works again without reinstalling. Environments venvctl creates are relocatable and never need it. |
| Editor visibility | Central environments are linked to their project through a PEP 832 .venv redirect file. |
| Diagnostics | doctor checks the Microsoft Store python.exe stub, the ExecutionPolicy scope that blocks your profile, long paths, the VC++ runtime, shell hooks and venvs inside cloud-synced folders. |
| Scriptable | Every command that prints results supports --json, and exit codes are fixed: 0 ok, 1 failure, 2 usage, 3 refused, 4 nothing to do. |
Installation
Requirements: Windows 10 or 11 (x64 or arm64). No admin rights needed. Python itself is not required to install venvctl; uv is used for create when it is installed.
1. Get venvctl.exe
Every option installs the same single binary. Pick one.
The winget package is waiting for Microsoft's review. Until it shows up, use any of the other options.
winget
winget install Kcodess2807.venvctl
Installer script. Downloads the latest release, checks it against SHA256SUMS, puts venvctl.exe in %LOCALAPPDATA%\venvctl\bin and adds that folder to your user PATH. It does not touch your shell profiles.
irm https://raw.githubusercontent.com/Kcodess2807/venvctl/main/install.ps1 | iex
pip. The package is called venvctl-win; the name venvctl on PyPI belongs to an unrelated project.
pip install venvctl-win
pip puts venvctl.exe in that Python's Scripts\ folder. If venvctl is then "not recognized", that folder is not on your PATH; run python -m venvctl_win init instead in step 2. The hooks store the full path to the exe, so on/off/cd keep working either way.
uv. Same package, installed as a tool in its own isolated environment:
uv tool install venvctl-win
If venvctl is "not recognized" afterwards, run uv tool update-shell once and open a new terminal.
Just trying it? uvx runs venvctl without installing anything. Good for the read-only commands:
uvx --from venvctl-win venvctl doctor # what's wrong with this machine's Python setup
uvx --from venvctl-win venvctl scan # find every venv on your drives
on, off and cd need the shell hooks from step 2, which point at a fixed exe path, so use a real install for those.
Build from source (works today; needs Go 1.26 or newer):
git clone https://github.com/Kcodess2807/venvctl
cd venvctl
go build -o venvctl.exe ./cmd/venvctl
# put it in a folder on your user PATH
$bin = "$env:LOCALAPPDATA\venvctl\bin"
New-Item -ItemType Directory -Force $bin | Out-Null
Copy-Item venvctl.exe $bin
[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";$bin", "User")
Open a new terminal so the new PATH is picked up.
Release zips with SHA256SUMS and a Scoop manifest will also be on the Releases page.
2. Install the shell hooks
on, off and cd change your current shell, which needs a small hook in each shell's startup file (PowerShell $PROFILE, the CMD AutoRun registry value, Git Bash .bashrc). Preview first, then install:
venvctl init --dry-run # shows every change it would make, changes nothing
venvctl init # installs the hooks
Open a new terminal afterwards. If PowerShell refuses to load your profile ("running scripts is disabled"), venvctl doctor names the policy scope responsible and the fix.
3. Check it works
venvctl version # the installed version
venvctl doctor # checks PATH, the Store python stub, ExecutionPolicy, hooks and more
cd D:\code\your-project
venvctl on # activates the nearest .venv; your prompt shows its name
venvctl off
Updating
Re-run the same install command (winget upgrade Kcodess2807.venvctl, the installer script, pip install -U venvctl-win, or uv tool upgrade venvctl-win). If the exe moved to a new folder, run venvctl init again; venvctl doctor warns when a hook points at an old path.
Uninstalling
venvctl init --remove # removes the hooks from every shell
Then remove the binary the way you installed it (winget uninstall Kcodess2807.venvctl, pip uninstall venvctl-win, uv tool uninstall venvctl-win, or delete %LOCALAPPDATA%\venvctl\bin and its PATH entry). Your venvs and venvctl's registry live in %LOCALAPPDATA%\venvctl; delete that folder too only if you no longer want the central venvs inside it.
Usage
venvctl on # activate the nearest .venv
venvctl on api # activate by name or path
venvctl off
venvctl create api # central environment, linked to the current folder
venvctl create --local # .\.venv in the current folder
venvctl scan # register every venv on your drives
venvctl list --sort size # see them with size and last use
venvctl prune --older-than 180d --dry-run
venvctl nuke old-api # delete, unlocking first
venvctl repair --dry-run # preview the fix for a moved venv
venvctl doctor # diagnose this machine's Python setup
Run venvctl --help for the full command list, or venvctl <command> --help for details and examples.
Auto-activation
venvctl config auto-activate on # once; takes effect in new terminals
cd D:\code\api
venvctl allow # trust this project root
From then on, entering the project activates its venv and leaving deactivates it. Environments you or your editor activated by hand are never touched. In CMD this requires Clink and is experimental.
How it works
venvctl on ──► shell function ──► venvctl.exe prints a script ──► the shell evaluates it in place
(installed once by `venvctl init` in $PROFILE, the CMD AutoRun registry value and .bashrc)
A child process cannot modify its parent shell's environment, so venvctl uses the same pattern as fnm, zoxide and starship: the binary prints shell code and a small function evaluates it. PowerShell still has to load your profile; if your execution policy prevents that, venvctl doctor names the scope responsible and the fix.
Full details, including the Restart Manager integration, launcher formats handled by repair, and the trust model, are in the design notes and the project record.
Comparison
| Activate in every shell | Find venvs across drives | Delete a locked venv safely | Repair a moved venv | |
|---|---|---|---|---|
| uv | – | – | – | avoided via --relocatable |
| VS Code | its own terminals | workspace only | – | – |
| PowerToys File Locksmith | – | – | finds more lockers; --kill stops all of them, no delete |
– |
| killpy | – | ✓ more environment types | plain delete | – |
| venvctl | ✓ | ✓ | ✓ attribution, editor protection, rename-first | ✓ pip, venv and older uv |
Status
v0.1.0 is the first release. The binaries are not code-signed yet, so Windows SmartScreen or your antivirus may warn on first run; every release lists the SHA256 of each file in SHA256SUMS.
- Tested on Windows 11 with PowerShell 5.1, CMD and Git Bash.
- CMD auto-activation (Clink), oh-my-posh and starship integration are untested.
- Repair of launchers written by uv 0.9.9 and later is verified against synthetic launchers only.
Documentation
- Design: architecture and command flows
- JSON output: schemas and exit codes
- Redirect files: how PEP 832
.venvfiles are used - Project record: everything built, tested and decided
License
Metadata
Release files for venvctl-win 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| venvctl_win-0.1.0-py3-none-win_arm64.whl | Python 3 | none | Windows ARM64 | Details for venvctl_win-0.1.0-py3-none-win_arm64.whl |
| venvctl_win-0.1.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details for venvctl_win-0.1.0-py3-none-win_amd64.whl |
Total release size: 7.1 MB
Release files / venvctl_win-0.1.0-py3-none-win_arm64.whl
| Download URL | venvctl_win-0.1.0-py3-none-win_arm64.whl |
|---|---|
| Size | 3.4 MB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
ee952f89ab7b70a2bb22743cd26c0ce920cf03df67faca1ec9b5efbc3cda0c16
|
|
BLAKE2b-256 checksum How to use checksums |
a660d759e969a678bcb04fcc531f3251ec5936972aaf7aa2bec21fde88d10672
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logRelease files / venvctl_win-0.1.0-py3-none-win_amd64.whl
| Download URL | venvctl_win-0.1.0-py3-none-win_amd64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
de6fef2776df6033937bcce5f3b4fd881c4a92848650096bb309673c49a07640
|
|
BLAKE2b-256 checksum How to use checksums |
5b6b975b5164c1a14379dd794f2d9c2053408f1f84938191537d4f0a07a300de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logSecurity for venvctl-win 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for venvctl_win-0.1.0-py3-none-win_arm64.whl
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.