Context
I downgraded my python to 3.4.4
so I could use the cx_Freeze module
since I want my script in exe format
so that I can send it to a friend of mine who doesn't have python.
I have figured out how it works on a single script with no modules imported. This is a problem since I wrote a script that functions like an alarm clock earlier, but to play the selected wav file (input being the filename) I needed a third party module called simpleaudio.
Question
How can I make the exe run the script properly?
Code
alarm.py:
import simpleaudio
import subprocess
import datetime
print("Set a wav audio file")
wav = input()
wav = str(wav)
print("Set alarm time")
print("hour.minute")
alarmtime = input()
alarmtime = str(alarmtime)
while alarmtime != "%02d.%02d" % (datetime.datetime.now().time().hour, datetime.datetime.now().time().minute):
print("%02d.%02d.%02d" % (datetime.datetime.now().time().hour, datetime.datetime.now().time().minute, datetime.datetime.now().time().second))
print("Playing",wav)
wave_obj = simpleaudio.WaveObject.from_wave_file(wav)
play_obj = wave_obj.play()
play_obj.wait_done()
setup.py:
import cx_Freeze
import sys
import simpleaudio
import subprocess
import datetime
executables = [cx_Freeze.Executable("alarm.py")]
cx_Freeze.setup(
name = "alarm",
options = {"build_exe": {"packages":["simpleaudio","subprocess","datetime"], "include_files":["rasputin.wav"]}},
executables = executables
)
Related
I have a tkinter application which I convert to exe with pyinstaller.
In the app user can configure (add their own scripts) to be executed.
**
I have a following code:
script_ABC = config['setup']['script_ABC']
exec(f"from user_scripts.{script_ABC} import *")
my config.ini file looks as follows:
[setup] script_ABC = s1.py
And this works before converting to exe, but after converting to exe not any more.
By working I mean that:
user can create a script: s2.py,
paste it into folder: ./user_scripts,
adjust config.ini as follows: script_ABC = s2.py
I'm using this code to determine paths:
if getattr(sys, 'frozen', False):
application_path = path.dirname(sys.executable)
elif __file__:
application_path = path.abspath(path.dirname(__file__))
so this is not an issue.
Any ideas how to achieve what I want with an alterantive approach?
I tried different locations, importlib, etc
I have been working on an automation script which includes shutting down my Windows 10 pro machine.
Here is one Python code which turned to exe file
import os
import time as t
import re
while True:
To check for "sd" in a file
lst = os.listdir("attachments")[-1]
with open(f"attachments\\{lst}", "r") as f:
message = f.read()
x = re.search("sd", message)
if "sd" is found then the file must be deleted and the computer must be shut down
if x:
print("YESSSS")
os.remove(f"attachments\\{lst}")
os.system("shutdown /s /t 1")
t.sleep(5)
The problem is that after deleting the file instead of shutting down the PC the cmd.exe appears on my screen...idk its weird
click for the image
to check if the exe format didnt have any problems i created another exe file
here is the code
import os
os.system("shutdown /s /t 1")
Turns out there is nothing wrong with the exe format...it performs normal shutdown....god just doesn't like me
Please help me 🥺
I'm having troubles with praw, cx_freeze, pyside and requests, before freezing everything works fine, but when i freeze this happens, something with requests goes wrong i think:
http://pastie.org/10614254
This is the project that i'm working with: https://github.com/MrCappuccino/WallDit-QT
This is my setup.py: https://gist.github.com/MrCappuccino/0f1b0571d29d47a95895
import sys
import cx_Freeze
import PySide
import praw
import requests.certs
from cx_Freeze import setup, Executable
exe = Executable(
script="WallDit_QT.py",
base="Win32GUI",
targetName="WallDit_QT.exe"
)
#includefiles = ['README.txt', 'CHANGELOG.txt', 'helpers\uncompress\unRAR.exe', , 'helpers\uncompress\unzip.exe']
#build_exe_options = {"packages": ["os"], "includefiles": ['README.txt', 'CHANGELOG.txt']}
setup(name = 'WallDit_QT',
version = '1.0',
author = 'Disco Dolan',
description ='Set your wallpaper interactively!',
executables = [exe],
options = {'build.exe': {"include_files":['cacert.pem', 'praw.ini', 'README.md']}},
requires = ['PySide', 'cx_Freeze', 'praw', 'shutil', 'requests']
)
could anybody help out?
I have tried adding cacert.pem, to no avail, at this point i have no more ideas
For some frozen applications, you have to set the the cacert (or external data in general) path inside the frozen applications.
Setup.py Section
You first need to include it in your build options and manually specify the installation directory. This is the only part that goes inside the setup.py:
# notice how I say the folder the certificate is installed
{"include_files":[(requests.certs.where(),'cacert.pem')]}
In your case, this produces the following setup file:
import requests
import sys
# more imports
setup(name = 'WallDit_QT',
version = '1.0',
author = 'Disco Dolan',
description ='Set your wallpaper interactively!',
executables = [exe],
options = {
'build.exe': {
"include_files": [
(requests.certs.where(),'cacert.pem'),
'praw.ini',
'README.md'
]
}
},
requires = ['PySide', 'cx_Freeze', 'praw', 'shutil', 'requests']
)
Application Section
You then need to get the certificate path at runtime inside the frozen application.
For PyInstaller, a path is defined at runtime to the data directory called _MEIPASS (which can be gotten from sys._MEIPASS), allowing you to access all the data required for the application. In the case of cacert.pem, the path would be determined as follows:
cacertpath = os.path.join(sys._MEIPASS, "cacert.pem")
For cx_Freeze, the path can be determined from the path of the installation and joining it with the data desired. Here, we get the path as follows:
cacertpath = os.path.join(datadir, 'cacert.pem')
You can get the data directory easily for frozen applications with the following:
datadir = os.path.dirname(sys.executable)
(Please note that this won't work with a non-frozen application, so to ensure it works for both frozen and non-frozen applications, Cx_Freeze recommends you code it as follows):
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
You then include this path all your requests module GET and POST requests as follows:
request.get(url, headers=headers, verify=cacertpath)
Example 1
An example code snippet would be as follows:
# load modules
import os
import sys
import requests
# define our path finder
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
# get our cacert path and post our GET request
cacertpath = find_data_file('cacert.pem')
r = requests.get('https://api.github.com/events', verify=cacertpath)
# print the text from the request
print(r.text)
Example 2
You can also tell requests where to find the certificate in the future by doing the following:
os.environ["REQUESTS_CA_BUNDLE"] = cacertpath
In this case, we would do the following. The advantage here is that the cacertpath does not to be explicitly defined in every module (or imported from another module) and can be defined in the environment.
import os
import sys
import requests
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
cacertpath = find_data_file('cacert.pem')
os.environ["REQUESTS_CA_BUNDLE"] = cacertpath
r = requests.get('https://api.github.com/events')
r.text
I have problem with playing .wav sound with QSound.play() after compiling to exe (I'm using Python 3.4.3, PyQt 5.4.1 and py2exe 0.9.2.0).
setup.py code:
from distutils.core import setup
import py2exe
setup(
windows=[
{
"script": "main_app.py",
"icon_resources": [(0, "favicon163248.ico")]
}
],
data_files=[
(
'sounds', ['sounds\Siren.wav']
)
],
options={"py2exe": {"includes": ["sip"], "dist_dir": "MyProject"}}
)
What have i tried:
Relative path
sound = QSound("sounds/Siren.wav")
sound.play() #works when simply running, doesn't work when compiling to exe
Path to executable file (main_app.exe)
sound = QSound(os.path.dirname(sys.executable) + "\sounds\Siren.wav")
sound.play() #doesn't work when compiling to exe
Absolute path
sound = QSound("C:\\path\\to\\project\\MyProject\\sounds\\Siren.wav")
sound.play() #works when simply running, doesn't work when compiling to exe
Resources
resources_qrc.qrc code:
<RCC>
<qresource prefix="media">
<file>Siren.wav</file>
<file>favicon163248.ico</file>
</qresource>
</RCC>
then converted to resources.py with pyrcc5
from resources import *
...
sound = QSound(':/media/Siren.wav')
sound.play() #works when simply running, doesn't work when compiling to exe
Copy form resource to hard drive on the fly
QFile.copy(":/media/Siren.wav", "sounds/Siren.wav")
sound = QSound("sounds/Siren.wav")
sound.play() #still doesn't work after making exe!
After spending pretty much time on it, I gave up.
Any help would be appreciated.
I use python 2.7 and cx_Freeze 4.3.1 and PyQt4
#-*- coding: utf-8-*-
__author__ = 'Aaron'
from cx_Freeze import setup, Executable
import sys
if sys.platform == "win32":
base = "Win32GUI"
includefiles= ['icons','Sound','imageformats']
includes = ['sip', 'PyQt4.QtCore']
setup(
name = u"Your Programe",
version = "1.0",
description = u"XXXX",
options = {'build_exe': {'include_files':includefiles}},
executables = [Executable("Your programe name.py" ,base = base, icon = "XXX.ico")])
I had the same problem too, with Python 3.4.3, PyQt 5.5.1, py2exe 0.9.2.2.
Problem is not in wrong file path.
If you call:
QAudioDeviceInfo.availableDevices(QAudio.AudioOutput)
from .exe, the returned list will be empty.
You should add foder: "\audio" from "site-packages\PyQt5\plugins" to the directory with your output .exe file, and sound will work.
Here is my setup.py file:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from distutils.core import setup
import py2exe
import sys
import os, os.path
import zipfile
import shutil
def get_exe_name(f):
dirname, filename = os.path.split(os.path.abspath(f))
return os.path.split(dirname)[-1].lower()
def get_name(name):
idx = name.find('.')
if idx != -1:
return name[:idx]
return name
def build(__version__, __appname__, main_module = 'main.py', dest_base='main', icon='images\\main.ico'):
#exec('from ' + get_name(main_module) + ' import __version__, __appname__')
try:
shutil.rmtree('dist')
except:
print ('Cann\'t remove "dist" directory: {0:s}'.format(str(sys.exc_info())))
if len(sys.argv) == 1:
sys.argv.append('py2exe')
options = {'optimize': 2,
# 'bundle_files': 0, # create singlefile exe 0
'compressed': 1, # compress the library archive
'excludes': ['pywin', 'pywin.debugger', 'pywin.debugger.dbgcon', 'pywin.dialogs', 'pywin.dialogs.list', 'os2emxpath', 'optparse', 'macpath', 'tkinter'],
'dll_excludes': ['w9xpopen.exe', 'mapi32.dll', 'mswsock.dll', 'powrprof.dll', 'MSVCP90.dll', 'HID.DLL'], # we don't need this
'includes': ['sip', 'locale', 'calendar', 'logging', 'logging.handlers', 'PyQt5', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtMultimedia', 'PyQt5.QtNetwork', 'PyQt5.QtPrintSupport'],
}
#datafiles = [('platforms', ['C:\\Python34\\Lib\\site-packages\\PyQt5\\plugins\\platforms\\qwindows.dll']),]
import PyQt5
datafiles = [('platforms', [PyQt5.__path__[0] + '\\plugins\\platforms\\qwindows.dll']), ('audio', [PyQt5.__path__[0] + '\\plugins\\audio\\qtaudio_windows.dll']),]
dirs = ['images', 'docs', 'ssl', 'sounds', 'p2ini', 'lib', 'config']
for d in dirs:
try:
for f in os.listdir(d):
f1 = d + '\\' + f
if os.path.isfile(f1): # skip directories
datafiles.append((d, [f1]))
except:
print ('Cann\'t find some files in directory "{0:s}": {1:s}'.format(d, str(sys.exc_info())))
setup(version = __version__,
description = __appname__,
name = '{0:s} {1:s} application'.format(__appname__, __version__),
options = {'py2exe': options},
zipfile = None,
data_files = datafiles,
windows = [{'icon_resources':[(1,'images\\main.ico')], 'script':main_module, 'dest_base':dest_base}] if icon else [{'script':main_module, 'dest_base':dest_base}],
scripts = [main_module],
#console = [{'icon_resources':[(1,'images\\main.ico')], 'script':main_module, 'dest_base':dest_base}] if icon else [{'script':main_module, 'dest_base':dest_base}],
)
And example code for call setup.py functions:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from setup import get_name, get_exe_name, build
MAIN_MODULE = 'main.py'
exec('from ' + get_name(MAIN_MODULE) + ' import __version__, __appname__')
build(__version__, __appname__, MAIN_MODULE, dest_base=get_exe_name(__file__))
I have a python script which gets an image from the internet, downloads it, sets as desktop background and updates after on minute. The problem is most likely cx_Freeze not including the os module, as the same code with absolute paths works fine. My code also works perfectly, until it goes through freezing. It works before it is frozen when I load throught the console, run from IDLE or double-click on it. Whenever i run the frozen file I get the error (If i use setup.py or cxfreeze file.py:
C:\Python33\Scripts>C:\Python33\Scripts\dist\desktopchanger.exe
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\cx_Freeze\initscripts\Console3.py", line 2
7, in <module>
exec(code, m.__dict__)
File "C:\Python33\desktopchanger.pyw", line 7, in <module>
dir = path.dirname(__file__)
NameError: name '__file__' is not defined
My Code
import pythoncom
from urllib import request
from win32com.shell import shell, shellcon
from time import sleep
from os import path
dir = path.dirname(__file__) #get dierctory script is in
startpath = str(path.join(dir+'/bg/bg.jpg')) #add /bg/bg.jpg to path of script
pathtoimg=[]
for char in startpath:
if char != "/":
pathtoimg.append(char) #replace / with \, necessary for setting bg
else:
pathtoimg.append("\\")
newpath = "".join(pathtoimg)
def get_image():
f = open(newpath, 'wb') #open .....\bg\bg.jpg
f.write(request.urlopen('http://blablabl.com/totale.jpg? i=0.387725243344903').read()) #get image from web and write over previous file
f.close()
while 1:
get_image()
#sets background below
iad = pythoncom.CoCreateInstance(shell.CLSID_ActiveDesktop, None,
pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IActiveDesktop)
iad.SetWallpaper(newpath, 0)
iad.ApplyChanges(shellcon.AD_APPLY_ALL)
sleep(60)
setup.py
from cx_Freeze import setup, Executable
exe=Executable(
script="desktop_changer_with_url2.py",
base="Win32Gui",
icon="icon.ico"
)
includes = ["os","urllib","time","pythoncom","win32com.shell"]
setup(
name = "Heindl Webcam als Desktop" ,
version = "1",
description = "eowjbadpoaäbaaplabipösdbjosdobsaboösac bjcaähpdaöbökabidsidsöds.",
executables = [exe],
)
Source:
http://cx-freeze.readthedocs.org/en/latest/faq.html
Your old line:
dir = path.dirname(__file__)
Substitute this with the following lines to run your script both frozen or unfrozen:
if getattr(sys, 'frozen', False):
# frozen
dir_ = os.path.dirname(sys.executable)
else:
# unfrozen
dir_ = os.path.dirname(os.path.realpath(__file__))
Tested with python 3.3.4. on win32
upd.: changed in accordance with the comment