Python安装Windows字体,打包成单个EXE文件

部署运行你感兴趣的模型镜像

一、主要目的

目的是在Windows系统中安装字体文件。具体功能包括:

  1. 将字体文件复制到系统的字体目录(Fonts文件夹)。

  2. 加载字体到当前会话。

  3. 通知其他运行的程序字体已更新。

  4. 在注册表中记录字体信息,以便系统识别和管理。

二、实现程序

import os
import shutil
import ctypes
from ctypes import wintypes
import sys
import time
import 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

gdi32.GetFontResourceInfoW.argtypes = (
    wintypes.LPCWSTR,  # lpszFilename
    wintypes.LPDWORD,  # cbBuffer
    wintypes.LPVOID,  # lpBuffer
    wintypes.DWORD)  # dwQueryType

def resource_path(relative_path):
    """获取资源文件的绝对路径"""
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

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))
    print("源路径: "+src_path)
    print("目标路径: "+dst_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 __name__ == "__main__":
    start_time = time.time()
    
    font_path = resource_path('SourceHanSansSC-Regular.otf')  # 安装思源黑体
    print("字体安装中,请稍等...")
    # 安装字体
    install_font(font_path)
    
    end_time = time.time()
    print("总共运行 %d 秒" % (end_time - start_time))
    time.sleep(1)

采用pyinstaller打包成单个EXE程序,注意字体文件SourceHanSansSC-Regular.otf要和该py文件放置在同目录下。打包命令:

pip install pyinstaller
pyinstaller --onefile --add-data="SourceHanSansSC-Regular.otf;." .\InstallerFront.py

三、程序说明

代码分为以下几个主要部分:

1. 导入模块:引入必要的系统模块和Windows API相关库。
2. Windows API配置:定义和配置与字体操作相关的Windows API函数和常量。
3. 辅助函数:提供资源路径解析功能。
4. 核心功能函数:实现字体安装的核心逻辑。
5. 主程序:调用核心功能函数完成字体安装。

 (1) 导入模块
  • os、shutil:用于文件路径操作和文件复制。
  • ctypes、wintypes:调用Windows API,与系统底层交互。
  • winreg:操作Windows注册表,记录字体信息。
  • sys、time:用于资源路径解析和计时。
(2)Windows API配置
  • user32和gdi32:通过ctypes加载Windows动态链接库(DLL),用于调用字体相关的API函数。
    •   AddFontResourceW:加载字体文件到当前会话。
    •   GetFontResourceInfoW:获取字体文件的详细信息(如字体名称、是否为TrueType字体)。
    •   SendMessageTimeoutW:广播消息通知其他程序字体已更新。
  • 常量和参数类型:定义了Windows消息类型(如WM_FONTCHANGE)和API函数的参数类型。
(3)辅助函数
  • resource_path:
    •   功能:解析资源文件的绝对路径。
    •   逻辑:优先尝试从sys._MEIPASS(PyInstaller打包时的临时目录)获取路径,否则使用当前目录。
(4)核心功能函数
  • install_font:
  1. 复制字体文件:将字体文件从源路径复制到系统的Fonts目录。
  2. 加载字体:使用AddFontResourceW加载字体到当前会话。如果失败,删除复制的文件并抛出异常。
  3. 通知其他程序:通过SendMessageTimeoutW广播WM_FONTCHANGE消息,通知其他程序字体已更新。
  4.  注册字体信息:使用GetFontResourceInfoW获取字体的真实名称和类型(如TrueType)。在注册表HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts中记录字体名称和文件名。
(5)主程序
  • 功能:
  1.   调用resource_path获取字体文件的路径。
  2.   调用install_font安装字体。
  3.   输出安装成功信息和运行时间。

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值