SHARE
TWEET

install fonts on windows 10 systems

DeaD_EyE Dec 6th, 2018 119 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Question came up here: https://www.facebook.com/groups/softwarehandwerk/permalink/731687033873815
  2. # stackoverflow says: https://stackoverflow.com/questions/41836528/install-a-font-using-python-in-windows
  3. # code is not tested!
  4.  
  5. import sys
  6. import os
  7. import shutil
  8. import ctypes
  9. from ctypes import wintypes
  10. from pathlib import Path
  11.  
  12. try:
  13.     import winreg
  14. except ImportError:
  15.     import _winreg as winreg
  16.  
  17. user32 = ctypes.WinDLL('user32', use_last_error=True)
  18. gdi32 = ctypes.WinDLL('gdi32', use_last_error=True)
  19.  
  20. FONTS_REG_PATH = r'Software\Microsoft\Windows NT\CurrentVersion\Fonts'
  21.  
  22. HWND_BROADCAST   = 0xFFFF
  23. SMTO_ABORTIFHUNG = 0x0002
  24. WM_FONTCHANGE    = 0x001D
  25. GFRI_DESCRIPTION = 1
  26. GFRI_ISTRUETYPE  = 3
  27.  
  28. if not hasattr(wintypes, 'LPDWORD'):
  29.     wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD)
  30.  
  31. user32.SendMessageTimeoutW.restype = wintypes.LPVOID
  32. user32.SendMessageTimeoutW.argtypes = (
  33.     wintypes.HWND,   # hWnd
  34.     wintypes.UINT,   # Msg
  35.     wintypes.LPVOID, # wParam
  36.     wintypes.LPVOID, # lParam
  37.     wintypes.UINT,   # fuFlags
  38.     wintypes.UINT,   # uTimeout
  39.     wintypes.LPVOID) # lpdwResult
  40.  
  41. gdi32.AddFontResourceW.argtypes = (
  42.     wintypes.LPCWSTR,) # lpszFilename
  43.  
  44. # http://www.undocprint.org/winspool/getfontresourceinfo
  45. gdi32.GetFontResourceInfoW.argtypes = (
  46.     wintypes.LPCWSTR, # lpszFilename
  47.     wintypes.LPDWORD, # cbBuffer
  48.     wintypes.LPVOID,  # lpBuffer
  49.     wintypes.DWORD)   # dwQueryType
  50.  
  51. def install_font(src_path):
  52.     # copy the font to the Windows Fonts folder
  53.     dst_path = os.path.join(os.environ['SystemRoot'], 'Fonts', os.path.basename(src_path))
  54.     shutil.copy(src_path, dst_path)
  55.     # load the font in the current session
  56.     if not gdi32.AddFontResourceW(dst_path):
  57.         os.remove(dst_path)
  58.         raise WindowsError('AddFontResource failed to load "%s"' % src_path)
  59.     # notify running programs
  60.     user32.SendMessageTimeoutW(HWND_BROADCAST, WM_FONTCHANGE, 0, 0, SMTO_ABORTIFHUNG, 1000, None)
  61.     # store the fontname/filename in the registry
  62.     filename = os.path.basename(dst_path)
  63.     fontname = os.path.splitext(filename)[0]
  64.     # try to get the font's real name
  65.     cb = wintypes.DWORD()
  66.     if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), None, GFRI_DESCRIPTION):
  67.         buf = (ctypes.c_wchar * cb.value)()
  68.         if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), buf, GFRI_DESCRIPTION):
  69.             fontname = buf.value
  70.     is_truetype = wintypes.BOOL()
  71.     cb.value = ctypes.sizeof(is_truetype)
  72.     gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), ctypes.byref(is_truetype), GFRI_ISTRUETYPE)
  73.     if is_truetype:
  74.         fontname += ' (TrueType)'
  75.     with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, FONTS_REG_PATH, 0, winreg.KEY_SET_VALUE) as key:
  76.         winreg.SetValueEx(key, fontname, 0, winreg.REG_SZ, filename)
  77.  
  78.  
  79. def install_fronts_from(path):
  80.     for font in Path(path).glob('*.ttf'):
  81.         install_font(font)
  82.  
  83.  
  84. if __name__ == '__main__':
  85.     if len(sys.argv) != 2:
  86.         print(sys.argv[0], 'path_to_fonts', file=sys.stderr)
  87.     else:
  88.         install_fronts_from(sys.argv[1])
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top