Skip to content

gh-85470: Delay load ole32.dll in the _ctypes module - #155435

Merged
serhiy-storchaka merged 1 commit into
python:mainfrom
serhiy-storchaka:gh-85470-ctypes-delayload-ole32
Aug 29, 2026
Merged

gh-85470: Delay load ole32.dll in the _ctypes module#155435
serhiy-storchaka merged 1 commit into
python:mainfrom
serhiy-storchaka:gh-85470-ctypes-delayload-ole32

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Aug 9, 2026

Copy link
Copy Markdown
Member

Measured on Windows 11 with a debug x64 build -- import _ctypes before the change loads user32.dll, ole32.dll, gdi32.dll, win32u.dll and combase.dll; after it, only combase.dll remains (pulled in by oleaut32, which does not depend on user32). A plain python.exe already loaded none of them, so ctypes was the last thing making the interpreter a GUI process -- and it is the module a console script needs in order to call SetConsoleCtrlHandler() in the first place.

ProgIDFromCLSID() in SetComError() is the only ole32 use in _ctypes, and it is reached only when formatting an error from a COM interface method. PCbuild/_wmi.vcxproj already delay loads the same DLL.

test_ctypes passes (679 tests). This covers the PCbuild build only; resolving ProgIDFromCLSID() through GetProcAddress() would also cover other toolchains, at the cost of some C code.

ole32.dll pulls in user32.dll, which makes the system treat the process as
a GUI process and stop sending logoff and shutdown console control events
to it.  It is only needed for ProgIDFromCLSID() when formatting a COM error.
@serhiy-storchaka

Copy link
Copy Markdown
Member Author

Verified the actual effect, not just the module list: two processes started from the same build in the same interactive session, one of them force-loading user32.dll to emulate the previous state, each with a SetConsoleCtrlHandler() installed through ctypes. On logoff the process without user32.dll received CTRL_LOGOFF_EVENT and ran its handler; the one with user32.dll loaded was terminated without any event.

@serhiy-storchaka
serhiy-storchaka merged commit 0e8100a into python:main Aug 29, 2026
52 checks passed
@serhiy-storchaka
serhiy-storchaka deleted the gh-85470-ctypes-delayload-ole32 branch August 29, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant