您的位置:首页 > 编程语言 > Python开发

windows下为Python脚本生成单独可执行程序的脚本(不用为每个脚本写setup.py了)

2007-11-01 10:15 931 查看
我们经常要用py2exe将python脚本转换为单独的可执行文件,但是有一个麻烦就是要针对脚本写一个setup.py,在setup.py中指定一些信息,然后运行setup.py py2exe来生成执行文件。为避免每次都要写setup.py,本人编写了一个工具脚本pyfly.py,只要运行pyfly.py yourfile.py就能生成yourfile.exe。还可以为其指定其他参数,比如-i myicon.ico为生成的可执行文件添加图标;-p console指定生成控制台程序,-p windows指定生成windows程序;-c yes指定用upx压缩可执行文件以减小大小,-c no执行不压缩可执行文件;-d out_directory 指定生成的可执行文件的输出目录。(-c yes 选项 需要将upx.exe放置在系统的环境变量PATH所包含的目录中,或者将upx.exe的路径加入PATH中)

运行"pyfly.py pyfly.py", 就立即在当前目录下生成pyfly.exe,将pyfly.exe置于环境变量PATH中能找到的位置,然后在任意目录中就可为你的python脚本生成单文件的可执行程序了。

#-*- coding: utf8 -*-

import os,sys,re,time,uuid,subprocess,shutil,WConio

def printgoodnews(news):

oldcolor=WConio.gettextinfo()[4]

WConio.textcolor(WConio.GREEN)

print news

WConio.textcolor(oldcolor)

def printbadnews(news):

oldcolor=WConio.gettextinfo()[4]

WConio.textcolor(WConio.RED)

print news

WConio.textcolor(oldcolor)

def delete_directory(path):

for root, subdirs,files in os.walk(path,topdown=False):

for file in files:

os.unlink(os.path.join(root,file))

for subdir in subdirs:

os.rmdir(os.path.join(root,subdir))

os.rmdir(path)

usage=r"""usage: pyfly script.py [-d out_directory] [-i iconfile] [-p console|windows] [-c yes|no]

('-c yes': call upx to compress exe)

e.g. : pyfly script.py -d c:\temp -i myicon.ico -p console

: pyfly script.py -d "c:\my directory"

"""

setuppy_console="""\

from distutils.core import setup

import py2exe

setup(

version = "",

description = "",

name = r"%s",

options = {"py2exe": {"compressed": 1,

"optimize": 2,

"ascii": 0,

"bundle_files": 1}},

zipfile = None,

# targets to build

console = [{"script": r"%s", "icon_resources": [(1, r"%s")]} ],

)

"""

setuppy_noicon_console="""\

from distutils.core import setup

import py2exe

setup(

version = "",

description = "",

name = r"%s",

options = {"py2exe": {"compressed": 1,

"optimize": 2,

"ascii": 0,

"bundle_files": 1}},

zipfile = None,

# targets to build

console = [{"script": r"%s", } ],

)

"""

setuppy_windows="""\

from distutils.core import setup

import py2exe

setup(

version = "",

description = "",

name = r"%s",

options = {"py2exe": {"compressed": 1,

"optimize": 2,

"ascii": 0,

"bundle_files": 1}},

zipfile = None,

# targets to build

windows = [{"script": r"%s", "icon_resources": [(1, r"%s")]} ],

)

"""

setuppy_noicon_windows="""\

from distutils.core import setup

import py2exe

setup(

version = "",

description = "",

name = r"%s",

options = {"py2exe": {"compressed": 1,

"optimize": 2,

"ascii": 0,

"bundle_files": 1}},

zipfile = None,

# targets to build

windows = [{"script": r"%s", } ],

)

"""

if __name__=="__main__":

if len(sys.argv)==1:

printgoodnews(usage)

sys.exit(-1)

script=sys.argv[1]

platform='console'

out_directory=os.getcwd()

iconfile=""

upx="no"

if script[-3:].lower()!=".py" or not os.path.exists(script):

printbadnews("%s is not a valid python source file or not exists!")

printgoodnews(usage)

sys.exit(-1)

try:

if len(sys.argv)>2 and len(sys.argv)<=8 and len(sys.argv) % 2==0:

options=[item.lower() for item in sys.argv[2::2]]

for option in options:

if option not in ['-p','-d','-i','-c']:

raise Exception(r'invalid option: %s!' % option)

if '-p' in options:

platform=sys.argv[sys.argv.index('-p')+1].lower()

if platform not in ['console','windows']:

raise Exception(r"%s is not a valid platform, you should use 'console' or 'windows'!" % platform)

if '-d' in options:

out_directory=sys.argv[sys.argv.index('-d')+1]

if not os.path.exists(os.path.abspath(out_directory)):

raise Exception(r"%s is not a valid directory!" % out_directory)

if '-i' in options:

iconfile=sys.argv[sys.argv.index('-i')+1]

if not os.path.exists(os.path.abspath(iconfile)) or iconfile[-4:].lower()!='.ico':

raise Exception(r"%s is not a valid icon file name or not exists!" % iconfile)

if '-c' in options:

upx=sys.argv[sys.argv.index('-c')+1].lower()

if upx not in ['yes','no']:

raise Exception(r"%s option must be set to 'yes' or 'no'!" % "-c")

elif len(sys.argv)==2:

pass

else:

raise Exception('Invalid counts of arguments!')

except Exception,e:

printbadnews(str(e))

printgoodnews(usage)

sys.exit(-1)

try:

tempdir=os.environ['temp']

#create setup.py in temp directory

setupfile=os.path.join(tempdir,str(uuid.uuid1())+".py")

while os.path.exists(setupfile):

setupfile=os.path.join(tempdir,str(uuid.uuid1())+".py")

g=open(setupfile,'wb')

if iconfile!="":

g.write(eval('setuppy_%s' % platform) % (os.path.basename(script),script,iconfile))

else:

g.write(eval('setuppy_noicon_%s' % platform) % (os.path.basename(script),script))

g.close()

del g

if " " in out_directory:

out_directory='"'+out_directory+'"'

cmd=r'python "%s" py2exe -O2 -d %s' %(setupfile,out_directory)

#print cmd

if subprocess.call(cmd)==0:

#delete temporary file and 'build' directory

os.unlink(setupfile)

cwd=os.getcwd()

build=os.path.join(cwd,'build')

bdist_win32=os.path.join(build,'bdist.win32')

delete_directory(bdist_win32)

#if build is a blank directory, delete it; otherwise keep it.

i=0

for root,subdirs,files in os.walk(build,topdown=True):

if subdirs!=[] or files!=[]:

i+=1

break

if i==0:

delete_directory(build)

# compress exe

if upx=='yes':

subprocess.call('upx -9 -v "%s.exe"' % os.path.join(out_directory,os.path.basename(script)[0:-3]))

except Exception,e:

printbadnews(str(e))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: