I am developing a python script to install a list of fonts in Windows. I have a list like this,
fonts_list = ["/path/to/file/myFont1.ttf", "/path/to/file/myFont1.ttf", "/path/to/file/myFont1.ttf"]
I simply tried, copying font files using both shutil and os, and after that I tried adding it to Windows registry, even with the admin privileges, it didn't work. Output from the script did not display any errors but there is no any font in Windows Fonts directory which are mentioned in the list.
os.system(reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "FontName (TrueType)")
So I started seeking more seeds from web and then I found this one, Installing TTF fonts on windows with python. But it didn't work too. Next I tried calling Windows fontview.exe, but for a list of fonts it is a disaster.
os.system("fontview " + fontsList[0])
Is there anyway to install a font in windows programmatically? Or is there any user level directory in Windows to simply copy font files like Linux systems have ~/.fonts and Macs have ~/Library/Fonts? Please help.
Here's an install_font
function to copy a font to the system Fonts folder, load it in the current session, notify running programs, and update the registry. It only depends on Python's standard library and should work in both Python 2 and 3.
ctypes definitions
import os
import shutil
import ctypes
from ctypes import wintypes
try:
import winreg
except ImportError:
import _winreg as winreg
user32 = ctypes.WinDLL('user32', use_last_error=True)
gdi32 = ctypes.WinDLL('gdi32', use_last_error=True)
FONTS_REG_PATH = r'Software\Microsoft\Windows NT\CurrentVersion\Fonts'
HWND_BROADCAST = 0xFFFF
SMTO_ABORTIFHUNG = 0x0002
WM_FONTCHANGE = 0x001D
GFRI_DESCRIPTION = 1
GFRI_ISTRUETYPE = 3
if not hasattr(wintypes, 'LPDWORD'):
wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD)
user32.SendMessageTimeoutW.restype = wintypes.LPVOID
user32.SendMessageTimeoutW.argtypes = (
wintypes.HWND, # hWnd
wintypes.UINT, # Msg
wintypes.LPVOID, # wParam
wintypes.LPVOID, # lParam
wintypes.UINT, # fuFlags
wintypes.UINT, # uTimeout
wintypes.LPVOID) # lpdwResult
gdi32.AddFontResourceW.argtypes = (
wintypes.LPCWSTR,) # lpszFilename
# http://www.undocprint.org/winspool/getfontresourceinfo
gdi32.GetFontResourceInfoW.argtypes = (
wintypes.LPCWSTR, # lpszFilename
wintypes.LPDWORD, # cbBuffer
wintypes.LPVOID, # lpBuffer
wintypes.DWORD) # dwQueryType
function definition
def install_font(src_path):
# copy the font to the Windows Fonts folder
dst_path = os.path.join(os.environ['SystemRoot'], 'Fonts',
os.path.basename(src_path))
shutil.copy(src_path, dst_path)
# load the font in the current session
if not gdi32.AddFontResourceW(dst_path):
os.remove(dst_path)
raise WindowsError('AddFontResource failed to load "%s"' % src_path)
# notify running programs
user32.SendMessageTimeoutW(HWND_BROADCAST, WM_FONTCHANGE, 0, 0,
SMTO_ABORTIFHUNG, 1000, None)
# store the fontname/filename in the registry
filename = os.path.basename(dst_path)
fontname = os.path.splitext(filename)[0]
# try to get the font's real name
cb = wintypes.DWORD()
if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), None,
GFRI_DESCRIPTION):
buf = (ctypes.c_wchar * cb.value)()
if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), buf,
GFRI_DESCRIPTION):
fontname = buf.value
is_truetype = wintypes.BOOL()
cb.value = ctypes.sizeof(is_truetype)
gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb),
ctypes.byref(is_truetype), GFRI_ISTRUETYPE)
if is_truetype:
fontname += ' (TrueType)'
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, FONTS_REG_PATH, 0,
winreg.KEY_SET_VALUE) as key:
winreg.SetValueEx(key, fontname, 0, winreg.REG_SZ, filename)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With