【问题标题】:How can I convince PyInstaller, via my spec file, to include libvlc.dll in the EXE it makes?如何通过我的规范文件说服 PyInstaller 在它制作的 EXE 中包含 libvlc.dll?
【发布时间】:2018-01-19 08:35:49
【问题描述】:

我可以使用在我的机器上运行的 PyInstaller 创建一个 EXE。我希望EXE真的是独立的,我希望而不是幻想。但是,EXE 不能在其他机器上运行。它因缺少 libvlc.dll 而窒息,错误消息称这可能是由于 PyInstaller 明显无法找到它。我已经用规范文件尝试了几件事,但都无济于事。我没有包含任何代码,因为我认为这无关紧要。这是我的规范文件:

# -*- mode: python -*-

block_cipher = None

added_files = [
     ( "D:/Applications/Python/Rogues Gallery/images/*.*", "images"),
     ( "D:/Applications/Python/Rogues Gallery/videos/*.*", "videos"),
     ( "D:/Applications/Python/MyMediaPlayer/icons/*.*", "icons")
     ]

a = Analysis(["Rogues_Gallery.py"],
         pathex=["D:/Applications/Python/Rogues Gallery/Rogues Gallery",
                 "C:/Program Files/VideoLAN/VLC/"],
         binaries=[("C:/Program Files/VideoLAN/VLC/plugins/*", "plugins"),
                   ("C:/Program Files/VideoLAN/VLC/libvlc.dll", ".")],
         datas=added_files,
         hiddenimports=[],
         hookspath=[],
         runtime_hooks=[],
         excludes=[],
         win_no_prefer_redirects=False,
         win_private_assemblies=False,
         cipher=block_cipher)

pyz = PYZ(a.pure, a.zipped_data,
         cipher=block_cipher)

exe = EXE(pyz,
      a.scripts,
      a.binaries,
      a.zipfiles,
      a.datas,
      name="Rogues_Gallery",
      debug=True,
      strip=False,
      upx=False,
      runtime_tmpdir=None,
      console=True )

在此规范文件上运行 PyInstaller 会生成包含以下行的记帐:

1677 WARNING: One binary added with two internal names.
1677 WARNING: ('libvlc.dll', 'C:\\Program Files\\VideoLAN\\VLC\\libvlc.dll', 'BINARY')
1678 WARNING: was placed previously at
1678 WARNING: ('libvlc.dylib', 'C:\\Program Files\\VideoLAN\\VLC\\libvlc.dll', 'BINARY')

顺便问一下,什么是“dylib”文件?这不是MAC的东西吗?它在我的PC上做什么?实际上,我在我的电脑上找不到“dylib”文件,除非是 PyInstaller 构建的结果;即运行EXE时MEIPASS临时文件夹中有一个libvlc.dylib;还有libvlc.dll。它似乎是 PyInstaller 正在创建的东西。如果我省略(“C:/Program Files/VideoLAN/VLC/libvlc.dll”、“.”),我不会收到警告,并且临时文件中不存在 libvlc.dll。奇怪的是,EXE 继续工作,所以 libvlc.dll 潜伏在某个地方。这就引出了一个问题:“EXE 真的是自给自足的,还是它在自身之外钓鱼,以便从宿主那里得到它所缺乏的东西?”也许,这就是为什么它可以在我的机器上运行,而不是在其他根本没有 libvlc.dll 的计算机上运行。

不管怎样,这里是我的 Rogues Gallery 导入:

try:
    import tkinter     as tk
    import tkinter.ttk as ttk
except ImportError:
    import tkinter as tk
    import ttk

from tkinter.filedialog import askopenfilename
from tkinter import messagebox
from tkinter.constants import *
from PIL import Image, ImageTk

import os
import sys
import pathlib
import random
from datetime import datetime
import time
import vlc
import MyMediaPlayer

“import vlc”不需要在那里,但我离开了它,因为这正是我一直在运行的方式;它应该出来。 Rogues Gallery 本身不做任何 vlc 的东西。 MyMediaPlayer.py 是我的 Python 脚本。这是所有 vlc 事情发生的地方。以下是它的导入:

try:
    import tkinter     as tk
    import tkinter.ttk as ttk
except ImportError:
    import tkinter as tk
    import ttk

from tkinter.filedialog import askopenfilename
from tkinter import messagebox
from tkinter.constants import *
from PIL import Image, ImageTk

import os
import sys
import vlc
import pathlib
import atexit
from threading import Thread, Event
import time
import platform

我已经尝试了我能想到的一切。我需要其他更好的思想家。

【问题讨论】:

    标签: python windows dll pyinstaller libvlc


    【解决方案1】:

    我不是 PyInstaller 方面的专家,我在明确包含的 Qt dll 上收到相同的警告。但是,我的 exe 在其他计算机上运行。您的代码是否将 sys._MEIPASS 添加到 libvlc.dll 的 python-vlc 搜索路径中? 影响:

    # handle pyInstaller temp directory 
    if hasattr(sys, '_MEIPASS'):
        # add to your python-vlc search path
    

    您正在测试的机器是否安装了 VLC?你能给出你在另一台机器上运行时看到的确切错误吗?

    【讨论】:

    • 如果不确定答案,请添加cmets
    • 是的,我的程序使用 _MEIPASS。我认为所有涉及的计算机上都安装了 VLC,但这有关系吗?
    • Traceback(最近一次调用最后):文件“Rogues_Gallery.py”,第 23 行,在 文件“”,第 971 行,在 _find_and_load 文件“”,第 955 行,在 _find_and_load_unlocked 文件中“”,第 665 行,在 _load_unlocked
    • 文件“d:\Downloads\PyInstaller\PyInstaller-3.3\PyInstaller\loader\pyimod03_importers.py”,第 631 行,在 exec_module 文件“site-packages\vlc.py”中,第 198 行 文件“site-packages\vlc.py”,第 173 行,在 find_lib 文件“PyInstaller\loader\pyiboot01_bootstrap.py”,第 151 行,在 init main .PyInstallerImportError:无法加载 dynlib/dll 'libvlc.dll'。当应用程序被冻结时,很可能没有找到这个 dynlib/dll。 [9084] 无法执行脚本 Rogues_Gallery
    【解决方案2】:

    成功!使用 PyInstaller 3.3.1(和 Python 3.6.4)我创建了一个可以在我的机器和其他机器上运行的 EXE,它可能与我的不同(不同的操作系统,没有 VLC 的东西等)。最后一个问题的答案很简单,但不容易找到。这对于我在 Python 旅程中遇到的每一个问题都是如此,从零开始到我第一个 Python 项目的终点线。解决方案是针对 VLC 正确配置规范文件。我仍然不够了解或无法解释,但这是工作规范文件。它可以为自己说话。也许,专家可以解释一下,这样其他人就不必经历我的所作所为。

    # -*- mode: python -*-
    
    block_cipher = None
    
    added_files = [
                   ("D:/Applications/Python/RoguesGallery/images/*.*", "images"),
                   ("D:/Applications/Python/RoguesGallery/videos/*.*", "videos"),
                   ("D:/Applications/Python/MyMediaPlayer/icons/*.*", "icons")
                  ]
    
    a = Analysis(['RoguesGallery.py'],
             pathex=["C:/Program Files/VideoLAN/VLC/"],
             binaries=[("C:/Program Files/VideoLAN/VLC/plugins/*", "plugins")],
             datas=added_files,
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
    
    pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
    
    exe = EXE(pyz,
          a.scripts,
          a.binaries + [("libVLC.dll", "C:/Program Files/VideoLAN/VLC/libvlc.dll", "BINARY")],
          a.zipfiles,
          a.datas,
          name='RoguesGallery',
          debug=False,
          strip=False,
          upx=False,
          runtime_tmpdir=None,
          console=False)
    

    我在这个项目中使用了 tkinter。我将在未来的项目中使用 PyQt5。我已经在使用它了。看这个视频。像我这样的 Emacs 和 Unix 人会很开心。 https://www.youtube.com/watch?v=ON0A1dsQOV0

    如果有人想把它拿出来试一试,我也可以提供来源。如果您想加快显示图像或“播放”文件或 GUI 内容的速度,我的小项目可能会对您有所帮助。它包括许多教学实验题外话,如何做到这一点,如何做那种事情。我的下一个项目是将这个项目从 tkinter 翻译成 PyQt5。继续编码!

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,你会惊讶于我做了什么让它工作。

      我从C:\Program Files\VideoLAN\VLC 获取所有文件并将它们加载到 dist 文件夹D:\Users\myprojects\python\musicPlayer\dist\main

      原因,pyinstaller 在编译时未能传输一些 VLC 库。

      所以我只是把它们都拿走了,没有过滤。我确定我也添加了一些不必要的文件,但它有效,所以我并不在乎。喜欢的可以一一浏览,我都加载了

      【讨论】:

        猜你喜欢
        • 2022-12-19
        • 2018-10-27
        • 2021-10-21
        • 2022-11-20
        • 2015-10-28
        • 1970-01-01
        • 2013-06-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多