You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用cx_Freeze打包含subprocess的Python脚本时遇FileNotFoundError求助

问题描述

我编写了一个从.p12文件提取公钥的Python脚本,在Spyder中运行正常,但使用cx_Freeze打包为可执行文件后,运行时出现FileNotFoundError: [WinError 2] Das System kann die angegebene Datei nicht finden错误。

提取公钥的脚本代码(extract_pubkey.py)

import os
import pandas as pd
import subprocess

def extract_public_key_from_p12_and_match_password(excel_file_path, p12_folder, output_folder):
       
    excel_data = pd.read_excel(excel_file_path)

    p12_files = [file for file in os.listdir(p12_folder) if file.endswith('.p12')]

    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    for p12_file in p12_files:
        email = p12_file.split('_')[1].replace('-', '.')

        password = excel_data.loc[excel_data['Email'] == email, 'Password'].values
        if len(password) == 0:
            print(f"Password not found {email}")
            continue

        password = password[0]

        input_path = os.path.join(p12_folder, p12_file)
        output_path = os.path.join(output_folder, f'{p12_file.replace(".p12", "_pubkey.pem")}')
        command = ['openssl', 'pkcs12', '-in', input_path, '-clcerts', '-nokeys', '-out', output_path, '-passin', f'pass:{password}']

        subprocess.Popen(command)
        print(f"Public key saved {email}.")

excel_file_path = r'.\myfile.xlsx'
p12_folder = r'.\p12-folder'
output_folder = r'.\pubcert-folder'

extract_public_key_from_p12_and_match_password(excel_file_path, p12_folder, output_folder)

cx_Freeze打包配置(setup.py)

import sys
import os.path
from cx_Freeze import setup, Executable

main_script = 'extract_pubkey.py'

executables = [Executable(main_script, base = None)]

build_exe_options = {
    "packages": ['subprocess', 'os', 'pandas', 'pip', 'cryptography'],
}

setup(
    name = 'name',
    version = '0.1',
    options={"build_exe": build_exe_options},
    executables = executables
)

运行exe时的错误信息

Traceback (most recent call last):
  File "C:\Users\MyUser\Desktop\...\venv_pubcert\Lib\site-packages\cx_Freeze\initscripts\__startup__.py", line 124, in run
    module_init.run(name + "__main__")
  File "C:\Users\MyUser\Desktop\...\venv_pubcert\Lib\site-packages\cx_Freeze\initscripts\console.py", line 16, in run
    exec(code, module_main.__dict__)
  File "extract_pubkey.py", line 53, in <module>
  File "extract_pubkey.py", line 44, in extract_public_key_from_p12_and_match_password
  File "C:\Users\MyUser\anaconda3\lib\subprocess.py", line 858, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Users\MyUser\anaconda3\lib\subprocess.py", line 1311, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] Das System kann die angegebene Datei nicht finden
解决方案

错误核心是打包后的可执行文件找不到openssl命令,以下是三种可行解决思路:

1. 直接指定openssl完整路径

修改脚本中调用openssl的部分,替换为系统中openssl可执行文件的绝对路径:

# 替换为你本地openssl的实际安装路径
openssl_path = r'C:\Program Files\OpenSSL-win64\bin\openssl.exe'
command = [openssl_path, 'pkcs12', '-in', input_path, '-clcerts', '-nokeys', '-out', output_path, '-passin', f'pass:{password}']

2. 将openssl文件打包到输出目录

  • 找到openssl安装目录下的openssl.exe及依赖dll文件(如libcrypto-1_1-x64.dll、libssl-1_1-x64.dll)
  • 修改setup.py,添加include_files参数将这些文件打包:
build_exe_options = {
    "packages": ['subprocess', 'os', 'pandas', 'pip', 'cryptography'],
    "include_files": [
        r'C:\Program Files\OpenSSL-win64\bin\openssl.exe',
        r'C:\Program Files\OpenSSL-win64\bin\libcrypto-1_1-x64.dll',
        r'C:\Program Files\OpenSSL-win64\bin\libssl-1_1-x64.dll'
    ]
}
  • 同时修改脚本,动态获取打包后的openssl路径:
import sys
# 判断是否为打包后的运行环境
if getattr(sys, 'frozen', False):
    openssl_path = os.path.join(sys._MEIPASS, 'openssl.exe')
else:
    openssl_path = 'openssl'

command = [openssl_path, 'pkcs12', '-in', input_path, '-clcerts', '-nokeys', '-out', output_path, '-passin', f'pass:{password}']

3. 使用Python库替代openssl命令行

用cryptography库直接处理p12文件,彻底避免依赖外部命令,是最稳定的方案:

import os
import pandas as pd
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import pkcs12

def extract_public_key_from_p12_and_match_password(excel_file_path, p12_folder, output_folder):
       
    excel_data = pd.read_excel(excel_file_path)

    p12_files = [file for file in os.listdir(p12_folder) if file.endswith('.p12')]

    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    for p12_file in p12_files:
        email = p12_file.split('_')[1].replace('-', '.')

        password = excel_data.loc[excel_data['Email'] == email, 'Password'].values
        if len(password) == 0:
            print(f"Password not found {email}")
            continue

        password = password[0].encode('utf-8')

        input_path = os.path.join(p12_folder, p12_file)
        output_path = os.path.join(output_folder, f'{p12_file.replace(".p12", "_pubkey.pem")}')

        # 读取p12文件
        with open(input_path, 'rb') as f:
            private_key, certificate, additional_certificates = pkcs12.load_key_and_certificates(
                f.read(),
                password=password,
                backend=default_backend()
            )
        
        # 导出公钥
        if certificate:
            public_key_pem = certificate.public_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PublicFormat.SubjectPublicKeyInfo
            )
            with open(output_path, 'wb') as f:
                f.write(public_key_pem)
            print(f"Public key saved {email}.")
        else:
            print(f"No certificate found in {p12_file} for {email}")

excel_file_path = r'.\myfile.xlsx'
p12_folder = r'.\p12-folder'
output_folder = r'.\pubcert-folder'

extract_public_key_from_p12_and_match_password(excel_file_path, p12_folder, output_folder)

内容的提问来源于stack exchange,提问作者Aukru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 17:44:51