Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
FormatMessage() in python, for system messages.
__all__ = (
FormatMessageSystem,
LCID_ENGLISH,
LCID_NEUTRAL,
)
import ctypes
import ctypes.wintypes
LANG_NEUTRAL = 0x00
SUBLANG_NEUTRAL = 0x00
SUBLANG_DEFAULT = 0x01
LANG_ENGLISH = 0x09
SUBLANG_ENGLISH_US = 0x01
def MAKELANGID(primary, sublang):
return (primary & 0xFF) | (sublang & 0xFF) << 16
LCID_ENGLISH = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
LCID_DEFAULT = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
LCID_NEUTRAL = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
assert LCID_NEUTRAL == 0
FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100
FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
# Note: You probably want to use the builtin ctypes.FormatError instead: https://docs.python.org/3/library/ctypes.html#ctypes.FormatError
# CPython impl: https://github.com/python/cpython/blob/13c1c3556f2c12d0be2af890fabfbf44280b845c/Modules/_ctypes/callproc.c#L254
def FormatMessageSystem(id, langid=LCID_ENGLISH):
sys_flag = FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS
bufptr = ctypes.wintypes.LPWSTR()
chars = ctypes.windll.kernel32.FormatMessageW(sys_flag, None, id, langid, ctypes.byref(bufptr), 0, None)
if chars == 0:
chars = ctypes.windll.kernel32.FormatMessageW(sys_flag, None, id, LCID_NEUTRAL, ctypes.byref(bufptr), 0, None)
if chars == 0:
#XXX: You probably want to call GetLastError() here
return "FormatMessageW failed"
val = bufptr.value[:chars]
ctypes.windll.kernel32.LocalFree(bufptr)
return val
@kafkaesqu3

This comment has been minimized.

Copy link

kafkaesqu3 commented Oct 4, 2016

this is very useful, thanks. amazing how complicated windows makes it to print API error messages.

@brianmaissy

This comment has been minimized.

Copy link

brianmaissy commented Jan 29, 2020

in case it might be useful to anyone else, it looks like ctypes has this functionality built in:
https://docs.python.org/3/library/ctypes.html#ctypes.FormatError

@EBNull

This comment has been minimized.

Copy link
Owner Author

EBNull commented Jan 29, 2020

Huh, good catch, it does, and apparently has since 2.5. CPython source: https://github.com/python/cpython/blob/13c1c3556f2c12d0be2af890fabfbf44280b845c/Modules/_ctypes/callproc.c#L254

I suppose this Python implementation would be useful if you wanted a specific language.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.