pywin32: Windows APIs and COM from CPython
Python for Windows (pywin32) Extensions
At a glance
- What is it?
- pywin32 exposes large parts of the Win32 API and COM to Python. It is a Windows-only extension package, and the install path has changed since the binary installer era.
- Who is it for?
- Adopt pywin32 if your code must drive COM, Windows services or Win32 APIs from CPython on Windows, and you are prepared to run python -m pywin32_postinstall -install in the environment that owns the install. Do not adopt it if you need a cross-platform library or a pure-Python dependency: the README lists no Linux or macOS support and the wheels are Windows-only.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What pywin32 is for, and who ends up needing it
pywin32 is the Python for Win32 extensions package. The README describes it as providing "access to many of the Windows APIs from Python, including COM support". That single sentence covers a wide surface: COM automation, Windows services, the win32 API modules, adodbapi, isapi and the Pythonwin GUI environment, all of which live in this repository as separate top-level directories (win32/, com/, pythonwin/, adodbapi/, isapi/).
The audience is narrow and specific. If you are writing CPython code that has to talk to Outlook, Excel, the Windows registry, the event log, a Windows service control manager, or an existing in-house COM component, pywin32 is the standard route. If your code only needs to move files or parse text, it is the wrong dependency: you would be pulling a compiled Windows extension into a project that does not call any Windows-specific API.
One structural detail matters for how you read the rest of this article. The project is not a library you can port. The modules are compiled extensions built against the Windows SDK, and the README's troubleshooting section assumes a Windows filesystem layout with System32 and HKCU or HKLM registry writes. There is no documented Linux or macOS path.
How the COM and Win32 layer is actually put together
The repository layout shows the split clearly. C++ sources sit alongside SWIG/ interface definitions, and the build produces Python extension modules plus two shared libraries, pywintypesXX.dll and pythoncomXX.dll, where XX is the Python version. The README's troubleshooting section names both files directly, which tells you they are loaded at import time rather than linked statically.
That design has a consequence worth stating plainly: the Python package and the DLLs must match, and they must be the only copies on the path. The documented failure mode is an import that raises "The specified procedure could not be found" or "Entry-point not found". The README gives two causes. The first is upgrading an install where the post-install script had previously run, which leaves registry state and copied files pointing at the old build. The second is a second set of pywin32 DLLs somewhere else on the system, and the README explicitly names environments that ship pywin32 pre-installed, with anaconda as its example.
COM support is the part most users come for. The pythoncom module is what backs it, and the repository keeps COM-specific code under com/. The documentation situation is admitted in the README itself: "The docs are a long and sad story", with an online rendering of the old PyWin32.chm helpfile at mhammond.github.io/pywin32. Some of that content is auto-generated and current, some is very old. Type hints are not in this repository either; the README points to types-pywin32 on PyPI and to typeshed stubs, and asks that static-typing issues be raised there rather than here.
Installing pywin32 with pip, and running the post-install script
The README is direct about the install method: binaries are no longer supported, and pip is the path. Build 306 was the last release with .exe installers, and the README says you "really shouldn't use them".
The basic install is a single command:
python -m pip install --upgrade pywin32After that, some functionality needs a post-install step. The README is explicit that this script "should not be run inside virtual environments; it should only be run in global installs". For a global install, run either of these:
python -m pywin32_postinstall -installpywin32_postinstall -installThe README notes the difference between the two forms: the second is shorter but gives you no control over which Python environment is used. With normal permissions the changes are per-user, copying a few files to the root of your Python install and writing to HKCU. From an elevated process the changes are machine-wide, copying files into System32 and writing to HKLM.
That elevation choice is the one real decision in the install. Services need the machine-wide form, because the README states that the LocalSystem account typically cannot reach your local %USER% directory, so Python must be installed somewhere the service account can read pythonXX.dll and pywintypesXX.dll from. If you are only calling COM from an interactive script, the per-user install is enough.
For MSYS2 and MinGW users there is a separate route. The README points to the MINGW-packages repository, which maintains patches, and suggests installing from the MSYS2 package index:
pacman -S mingw-w64-python-pywin32The README adds that upstreaming those patches would require them to be testable automatically on CI, so treat the MSYS2 package as the supported path rather than a temporary one.
The upgrade traps: stale DLLs and the post-install script
The most common pywin32 failure is not a missing feature. It is an import error after an upgrade. The README lists the two symptoms, "The specified procedure could not be found" and "Entry-point not found", and ties them to a mismatch between the Python package and the on-disk DLLs.
If you upgraded an install where the post-install script had run before, the fix is to run it again. The README says it "will make some small attempts to cleanup older conflicting installs", which is a modest promise, not a guarantee. If that does not resolve it, the second cause applies: another copy of pywintypesXX.dll or pythoncomXX.dll exists somewhere else. The README suggests finding and removing all other copies, naming the files by pattern rather than by path, which means you have to search the filesystem yourself.
This is where pywin32 differs from a normal pip package. A pure-Python dependency can be upgraded and forgotten. Here, the package writes outside site-packages: files into the Python install root or System32, and keys into HKCU or HKLM. Uninstalling the pip package does not necessarily undo those writes. Anyone maintaining a long-lived Windows image should plan for that, and should check whether the base image already contains pywin32 before adding it.
The free-threaded interpreter is a second limitation, and the README is unusually blunt about it. Building with a no-GIL interpreter produces a wheel that is "compatible, but knowingly unsafe" and "should be considered experimental". No wheels for the free-threaded interpreter will be published; you can build your own. NOGIL.md in the repository lists the blockers. If your project depends on free-threading, pywin32 is not a dependency you can rely on today.
Where pywin32 is the wrong choice, and what to use instead
Two cases argue against pywin32 even on Windows.
The first is portability. If the same code must run on Linux or macOS, pywin32 cannot be part of it. There is no documented non-Windows build, and the modules are compiled against Windows headers. The usual alternative is ctypes, which ships with CPython and can call into shared libraries on any platform, or a higher-level wrapper that already abstracts the platform. The difference in approach is real: ctypes gives you raw function calls and you declare the signatures yourself, while pywin32 ships prebuilt bindings and a COM runtime (pythoncom) that you would otherwise have to construct. For a single Win32 call, ctypes is less machinery. For COM automation, it is a much longer road.
The second case is a project that only needs one narrow piece of Windows functionality. pywin32 is a large, compiled dependency, and its install touches the registry when the post-install script runs. If you need, say, the event log and nothing else, check whether a smaller package covers it before adding this one. The README does not offer a slimmed-down install, and there is no documented way to take only one module.
A middle option exists for typing. If you want signatures and annotations without changing runtime behaviour, the README points to types-pywin32 on PyPI and to the pywin32 stubs in typeshed. That is a separate package and a separate issue tracker, which is worth knowing before you file a typing bug against the main repository.
Maintenance, licensing and what an upgrade costs
The repository is not archived, and the last push was on 2026-09-08. Releases are numbered builds rather than semantic versions: b310 in March 2025, b311 in July 2025, b312 in June 2026. The setup.py in the repository carries build_id "312.1", which allows a patch suffix on top of a build number. The practical effect is that you pin a build, not a minor version, and a patch release can appear without a new build number.
Because the package installs DLLs and registry state, an upgrade is not a no-op. The README's own upgrade instructions require re-running the post-install script in global installs, and the troubleshooting section expects you to hunt for duplicate DLLs when that fails. Budget for that in any automated deployment: the pip upgrade alone is not the whole operation.
On licensing, the README's badge identifies the project as PSF-2.0, the Python Software Foundation License 2.0, and links to the SPDX identifier. The repository metadata shown here lists the licence as unknown, so treat the badge as the project's own statement and confirm it against the LICENSE file in the tree before you rely on it. That matters most if you redistribute the package or bundle it into a product, because the compiled DLLs and the Python code are covered by the same stated licence. This is a description of what the project says, not legal advice.
Support channels are split deliberately. Bugs go to GitHub issues; general questions and problems using the modules go to GitHub Discussions under the Q&A category, and the README warns that non-bug issues will be converted into discussions anyway. The python-win32 mailing list still exists for general Python-on-Windows help.
Editorial conclusion
Adopt pywin32 if your code must drive COM, Windows services or Win32 APIs from CPython on Windows, and you are prepared to run python -m pywin32_postinstall -install in the environment that owns the install. Do not adopt it if you need a cross-platform library or a pure-Python dependency: the README lists no Linux or macOS support and the wheels are Windows-only. Before committing, verify that a wheel exists for your Python version and architecture on PyPI, and check whether your deployment environment already ships pywintypesXX.dll, because duplicate DLLs are the documented cause of the entry-point errors.
Frequently asked questions
What is pywin32 used for?
It provides access to many of the Windows APIs from Python, including COM support. In practice that covers COM automation, Windows services and the win32 modules, with adodbapi, isapi and the pythonwin GUI environment in the same repository.
How do I install pywin32 on Windows?
Install it with pip using python -m pip install --upgrade pywin32. Binary .exe installers are no longer supported; build 306 was the last release that shipped them.
How do I install pywin32 in Python?
Run python -m pip install --upgrade pywin32 in the Python environment you intend to use. If you need COM objects or services registered, follow it with the post-install script in a global install, not a virtual environment.
Does pywin32 work on Linux or macOS?
The README documents no Linux or macOS support. It is a set of Windows extensions built against the Windows SDK, and the only non-Windows packaging route it mentions is MSYS2/MinGW via the mingw-w64-python-pywin32 package.
Is pywin32 safe?
The README does not address security directly. What it does say is that the post-install script writes files into your Python install root or System32 and changes HKCU or HKLM, so the permissions you run it with determine how far those changes reach.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mhammond-pywin32)