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

Python脚本转exe后无法打开PDF,且系统PDF也无法打开

问题:Python脚本转exe后无法打开PDF,且系统PDF关联异常

我开发的程序使用subprocess.Popen打开PDF文件,运行.py脚本时功能正常,但将脚本转换为.exe文件后,不仅无法通过该exe打开PDF,甚至运行该exe后,本机所有PDF文件都无法直接打开(包括从桌面双击打开)。

相关代码

# import _tkinter

import PyPDF2
import os
import json
import tkinter as tk
import subprocess

class FileLabels:
    def __init__(self):
        self.all_widgets = []

    def create_label(self, filename):
        new_label = tk.Label(text=filename)
        new_label.grid(row=6+found_files.index(filename), column=1)
        self.all_widgets.append(new_label)

    def create_copy_button(self, filename):
        new_button = tk.Button(text="Open", command=lambda: openfile(filename))
        new_button.grid(row=6+found_files.index(filename), column=2)
        self.all_widgets.append(new_button)

file_labels = FileLabels()

def openfile(filename):
    path = f'{directory}\\{filename}'
    subprocess.Popen([path], shell=True)

def external_get_folder():
    global folder_entry
    global start_window
    start_window = tk.Tk()
    start_window.title("BSP PDF Searcher")
    folder_label = tk.Label(text="1. Copy paste all PDF's into a folder on your computer.\n"
                                 "2. Copy paste the folder location here and click OK.\n"
                                 "Get some coffee. This may take a few minutes.")
    folder_label.grid(row=1, column=1)
    folder_entry = tk.Entry()
    folder_entry.grid(row=1, column=2)
    folder_button = tk.Button(text="OK", command=lambda: external_extract_pdf(widgets))
    folder_button.grid(row=2, column=2)
    widgets = []
    start_window.mainloop()

def external_extract_pdf(widgets):
    for i in widgets:
        i.destroy()
    global directory
    global search_entry
    global drawing_contents
    global files_in_folder
    global damaged
    try:
        directory = folder_entry.get()
    except _tkinter.TclError:
        pass

    #create dictionary of contents
    damaged = []
    files_in_folder = 0
    drawing_contents = {}

    for filename in os.listdir(directory):
        f = os.path.join(directory, filename)
        with open(f, "rb") as pdf_file:
            try:
                read_pdf = PyPDF2.PdfFileReader(pdf_file)
            except:
                pass
            else:
                files_in_folder += 1
            number_of_pages = read_pdf.getNumPages()
            page = read_pdf.pages[0]
            try:
                page_content = page.extractText().lower()
            except IndexError:
                damaged.append(filename)
            else:
                drawing_contents[filename] = page_content
    display_results()

def display_results():
    global search_entry
    global search_button
    try:
        start_window.destroy()
    except _tkinter.TclError:
        pass

    results_window = tk.Tk()
    results_window.title("BSP PDF Searcher")
    dir_label = tk.Label(text=f"Searching in {directory}\n{files_in_folder} files, {len(damaged)} damaged")
    dir_label.grid(row=1, column=1)
    search_label = tk.Label(text="Enter words to search: ")
    search_label.grid(row=3,column=1)
    search_entry = tk.Entry()
    search_entry.grid(row=3, column=2)
    search_button = tk.Button(text="Search", command=lambda: ext_search(widgets))
    search_button.grid(row=3, column=3)
    try:
        x = found_files_label
    except:
        found_files_label = tk.Label()
        found_count_label = tk.Label()
        widgets = []

def ext_search(widgets):
    global found_files_label
    global found_count_label
    global found_files

    for i in file_labels.all_widgets:
        i.destroy()

    try:
        found_count_label.destroy()
    except NameError:
        pass

    key_words_list = list(search_entry.get().split(" "))
    for i in widgets:
        i.destroy()
    found_count = 0
    found_files = []
    for filename, contents in drawing_contents.items():
        if all(i in contents for i in key_words_list):
            found_files.append(filename)
            found_count += 1

    for i in found_files:
        file_labels.create_label(i)
        file_labels.create_copy_button(i)

    found_count_label = tk.Label(text=f"{found_count} results:")
    found_count_label.grid(row=4,column=1)

external_get_folder()

解决办法

1. 替换PDF打开方式

原代码中subprocess.Popen的打开方式在打包成exe后存在兼容性问题,且可能干扰系统文件关联。改用Windows原生的os.startfile函数,它会直接调用系统默认程序打开指定文件,稳定性更强:

修改openfile函数:

def openfile(filename):
    path = os.path.join(directory, filename)  # 用os.path.join避免路径拼接错误
    os.startfile(path)

2. 修复原subprocess写法(备选)

如果坚持使用subprocess,需修正参数传递逻辑:当shell=True时,应将路径作为字符串传入,同时用start命令调用系统默认程序:

def openfile(filename):
    path = os.path.join(directory, filename)
    subprocess.Popen(f'start "" "{path}"', shell=True)

3. 检查打包参数

若使用PyInstaller打包,避免可能导致环境隔离异常的参数。比如单文件模式(-F)下部分系统调用可能受影响,可尝试用文件夹模式(-D)打包,确保所有依赖被正确包含。

恢复系统PDF关联

若已出现系统PDF无法打开的情况,可通过Windows设置恢复:

  • 打开「设置」→「应用」→「默认应用」
  • 进入「选择默认应用按文件类型」,找到.pdf格式,重新选择默认PDF阅读器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:45:33