python - cx_Freeze:主脚本中的 Python 错误 - ImportError:DLL 加载失败
问题描述
我正在构建一个小的 Python 3.6.5 工具,它接收一个 XML 文档并输出它的所有 XPath。它运作良好,但是我需要以 EXE 形式分发它。我在Win10上运行,只需要提供给Win10用户即可。
我的主要代码是;
from tkinter import filedialog
from tkinter import *
from pathlib import Path
import winsound
from lxml import etree
import csv
root = Tk()
root.geometry("250x200")
root.resizable(0, 0)
class gui:
def __init__(self, master):
self.master = master
master.title("XGen")
self.welcome = Label(master, text="Welcome to")
self.welcome.config(font=("Arial", 10))
self.welcome.pack()
self.header = Label(master, text="The XPath Generator")
self.header.config(font=("Arial", 16))
self.header.pack()
self.description = Label(master, text="This Tool Takes in an XML Document\nand Provides all its XPaths")
self.description.config(font=("Arial", 10))
self.description.pack()
self.greet_button = Button(master, text="Select Input XML", command=self.greet)
self.greet_button.pack()
self.reportFilename = Label(master, text="")
self.reportFilename.pack()
self.reportProgress = Label(master, text="")
self.reportProgress.pack()
# self.close_button = Button(master, text="Close", command=master.quit)
# self.close_button.pack()
def greet(self):
print("File Selection Started")
from_file_path = filedialog.askopenfilename(initialdir="/",
title="Select file",
filetypes=(("XML Files", "*.xml"), ("all files", "*.*")))
from_file_path_split = Path(from_file_path).parts
to_file_path = ''
if from_file_path is '':
self.reportFilename.config(text="You Did not Select a File")
print("No File Selected. File Selection Ended")
else:
self.reportFilename.config(text="You Selected " + from_file_path_split[-1])
print("From File Path = " + from_file_path)
print("File Name = " + from_file_path_split[-1])
to_file_path = filedialog.asksaveasfilename(initialdir=from_file_path,
title="Save As",
filetypes=(("CSV Files", "*.csv"), ("all files", "*.*")))
if to_file_path is '' or to_file_path == 'Null':
self.reportProgress.config(text="Please select a Save Location")
# elif to_file_split[-1][:4] == "xsd":
else:
to_file_split = Path(to_file_path).parts
to_file_name = to_file_split[-1]
print("Filename = " + to_file_name)
to_file_extension = to_file_split[-1][-4:]
print("Last 4 chars = " + to_file_extension)
if to_file_extension == ".csv":
pass
else:
to_file_path = to_file_path + ".csv"
# to_file_name = to_file_path
print("To File Path = " + to_file_path)
if from_file_path == '' or to_file_path == '' or to_file_path == 'Null':
self.reportProgress.config(text="Please Select a Valid XML File")
winsound.PlaySound("SystemExclamation", winsound.SND_ALIAS)
print("Bad File, Try Again")
else:
out(from_file_path, to_file_path)
self.reportProgress.config(text="Generated " + Path(to_file_path).parts[-1])
print("XGen Complete")
def out(in_path, out_path):
with open(in_path, 'r') as source_file:
xml = source_file.read()
root = etree.fromstring(xml)
tree = etree.ElementTree(root)
line = ['XPath', 'Attribute Name', 'Current Data']
if out_path is None:
return 1
else:
pass
with open(out_path, 'w', newline='') as csv_file:
csv_writer = csv.writer(csv_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
csv_writer.writerow(line)
for e in root.iter():
path = tree.getpath(e)
list_of_attributes = []
nodes = root.xpath(path)
for node in nodes:
attrs = []
for att in node.attrib:
attrs.append(("@" + att, node.attrib[att]))
list_of_attributes.append(attrs)
for attributes in list_of_attributes:
line = [path, None]
csv_writer.writerow(line)
if len(attributes) == 0:
pass
else:
for x in range(len(attributes)):
xpath = path + attributes[x][0]
current_data = (attributes[x][1])
attribute_name = attributes[x][0]
line = [xpath, attribute_name, current_data]
csv_writer.writerow(line)
my_gui = gui(root)
root.mainloop()
(请原谅凌乱的代码!我打算为下一个版本清理它!)
setup.py
包含以下内容;
import sys
from cx_Freeze import setup, Executable
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
executables = [
Executable('xin.py', base=base)
]
setup(name='XGen',
version='0.1',
description='XGen',
executables=executables
)
这确实允许程序构建一个 EXE,但是当该 EXE 运行时,它会返回此错误。
我一直在到处寻找解决方案。
- 我发现了一个建议,即卸载所有版本的 Python 然后只安装一个可能会起作用,但没有乐趣。
- 我以前尝试过 Py2exe,但这也不起作用。
- 我发现另一个建议 PATH 可能不正确,所以检查了一下,那里的一切似乎也正确。
正如错误文本所建议的那样,我还尝试检查 tkinter 是否已正确安装。这个程序不仅可以通过 Python 运行,IDLE 也让我import tkinter
.
什么可能导致 cx_Freeze 抛出此错误?
谢谢!
解决方案
TK DLL的位置需要添加到setup.py
. 在 Windows 10 上,这可能位于 C: 或C:\Users\[username]\AppData\Local\Programs\Python\Python36-32/DLLs
. 添加一个变量来存储该路径,然后使其成为带有前导的原始字符串r
。
import os
import sys
from cx_Freeze import setup, Executable
PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
syspath = r"C:\Users\[username]\AppData\Local\Programs\Python\Python36-32/DLLs"
buildOptions = dict(
packages=[],
excludes=[],
include_files=[syspath + '/tcl86t.dll', syspath + '/tk86t.dll']
)
executables = [
Executable('xin.py', base=base)
]
setup(name='XGen',
version='0.1',
options=dict(build_exe=buildOptions),
description='XGen',
executables=executables
)
非常感谢 MrLeeh 和 DeePak M. Birajdar!
推荐阅读
- 3dsmax - 按下 UI 按钮会扭曲模型
- cefsharp - Cefsharp 以画中画模式播放视频
- mysql - SQLSTATE[HY000] [2002] 在 laravel 和 docker 设置上连接被拒绝
- ios - 当我看到“将本地更改重新设置为上游更改”消息时,如何覆盖 XCode 存储库中的所有本地更改?
- javascript - 我想要日期范围选择器以及“DD/MM/YYYY”格式的输出数据
- scala - 使用 HBase Sink 的 Spark 结构化流
- mongodb - 如果输入数组的元素至少匹配一个,则获取数组的大小
- javascript - 当我在模板文字中使用 .map 时,为什么我的输出中有逗号?
- python - 按级别提取嵌套列表中的字符串
- python - 运行机器人文件的命令,我也可以在其中指定 python 版本