如何通过我的spec文件说服PyInstaller在其创建的EXE中包含libvlc.dll?

时间:2018-01-19 08:35:49

标签: python windows dll pyinstaller libvlc

我可以使用PyInstaller创建一个可在我的机器上运行的EXE。我充满希望,而不是妄想,我希望,EXE真的是自足的。但是,EXE不能在其他计算机上运行。它由于没有libvlc.dll而窒息,错误消息说这可能是由于PyInstaller显然无法找到它。我已经用spec文件尝试了几件事,但都无济于事。我没有包含任何代码,因为我不认为这是密切相关的。这是我的spec文件:

# -*- 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 )

在此spec文件上运行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

我已经尝试了所有我能想到的东西。我需要其他更好的思想家。

3 个答案:

答案 0 :(得分:0)

我不是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?您是否可以提供在尝试在另一台计算机上运行时看到的确切错误?

答案 1 :(得分:0)

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

# -*- 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。保持编码!

答案 2 :(得分:0)

我遇到了同样的问题,您会为我所做的使我感到惊讶的事情。

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

原因是pyinstaller在编译时无法转移某些VLC库。

因此,我将它们全部过滤掉了。我确定我也添加了一些不必要的文件,但是它可以工作,所以我不在乎。如果需要,您可以一个接一个地浏览它们,我刚刚加载了所有