我正在开发一个python脚本来安装Windows中的字体列表.我有这样的清单,
fonts_list = ["/path/to/file/myFont1.ttf", "/path/to/file/myFont1.ttf", "/path/to/file/myFont1.ttf"]
我只是尝试使用shutil和os复制字体文件,之后我尝试将其添加到Windows注册表中,即使使用管理员权限,它也无法正常工作.脚本的输出没有显示任何错误,但列表中提到的Windows Fonts目录中没有任何字体.
os.system(reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "FontName (TrueType)")
所以我开始从网上寻找更多的种子然后我找到了这个,用python在Windows上安装TTF字体.但它也没有用.接下来我尝试调用Windows fontview.exe,但是对于字体列表来说这是一场灾难.
os.system("fontview " + fontsList[0])
无论如何都要以编程方式在Windows中安装字体?或者Windows中是否有任何用户级目录只是复制字体文件,如Linux系统有〜/ .fonts和Mac有〜/ Library/Fonts?请帮忙.
这是install_font
将字体复制到系统Fonts文件夹,在当前会话中加载,通知正在运行的程序以及更新注册表的功能.它只依赖于Python的标准库,并且应该同时适用于Python 2和3.
ctypes的定义
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
功能定义
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)