商业软件要保护,内部工具也要防多开。

Windows文件锁防多开、日期检查限试用——简单够用。

一、两种保护机制

机制 目的 实现
单实例限制 防止多开 Windows文件锁
试用期限制 控制使用期限 日期检查

二、单实例限制(Windows文件锁)

python

import ctypes
from ctypes import wintypes

def check_single_instance(app_name="Metis_PhaseAnalyzer"):
    lock_file_path = os.path.join(
        os.path.dirname(os.path.abspath(__file__)), 
        f".{app_name}.lock"
    )
    
    GENERIC_READ = 0x80000000
    GENERIC_WRITE = 0x40000000
    FILE_SHARE_NONE = 0
    CREATE_ALWAYS = 2
    ERROR_SHARING_VIOLATION = 32
    
    CreateFileW = ctypes.windll.kernel32.CreateFileW
    WriteFile = ctypes.windll.kernel32.WriteFile
    GetLastError = ctypes.windll.kernel32.GetLastError
    
    # 以独占方式打开/创建锁文件
    handle = CreateFileW(
        lock_file_path,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_NONE,
        None,
        CREATE_ALWAYS,
        0,
        None
    )
    
    if handle == -1 and GetLastError() == ERROR_SHARING_VIOLATION:
        return False  # 已有实例
    
    # 写入进程ID
    pid_str = str(os.getpid()).encode('utf-8')
    bytes_written = wintypes.DWORD(0)
    WriteFile(handle, pid_str, len(pid_str), ctypes.byref(bytes_written), None)
    
    check_single_instance._lock_handle = handle
    return True

特性:进程崩溃自动释放锁(Windows系统自动关闭句柄)。

三、试用期限制

python

from datetime import datetime

EXPIRATION_DATE = datetime(2026, 8, 8)

def check_trial_period():
    current_date = datetime.now()
    return current_date <= EXPIRATION_DATE

# 使用
if __name__ == '__main__':
    if not check_trial_period():
        sys.exit(1)  # 静默退出

局限性:可被修改系统时间绕过。需要更强保护可加在线验证/代码混淆。

四、调用顺序

text

启动程序
    ↓
检查试用期 → 过期 → 静默退出
    ↓
检查单实例 → 已运行 → 提示后退出
    ↓
正常启动

下篇预告

下一篇写PyInstaller打包实战:spec配置、隐式导入、体积优化。

更多推荐