简单三步!Python封装成可带参数的EXE安装包

最近有一个小项目,有如下的需求:

将某几个源码文件夹进行打包,文件夹内有py文件、dll文件、exe文件等各种文件类型

打包生成的安装包,在进行安装的时候,应该能够带有参数,对配置文件进行修改配置

安装过程中,可以配置系统环境变量

能够检测环境,提示安装依赖包

整个过程要可以自动化,能够大量部署

综合考虑后,决定以下几个步骤完成:

用setup.py将源码文件夹都打包成msi安装包,这样可以使用msiexec进行静默安装

setup.py可以提示用户安装依赖包,否则安装失败

再编写一个py文件,用来静默安装msi安装包,并配置系统环境变量,接受安装参数去修改配置文件的属性

最后使用pyinstaller将所有都打包成exe文件

先来编写setup.py文件:

<code> 

from

distutils.core

import

setup

import

os

def

get_all_dir

(path)

:

""" 获取指定路径下的所有文件 """

all_file = []

for

dirpath, dirnames, filenames

in

os.walk(path):

for

filename

in

filenames: all_file.append(dirpath)

return

all_file

if

__name__ ==

'__main__'

: all_file = get_all_dir(

'A'

) + get_all_dir(

'B'

) setup(name=

'Example'

, version=

"1.0"

, description=

"This is example"

, author=

"author"

, author_email=

'my email'

, packages=all_file, package_data={

''

: [

'*.*'

]}, classifiers=[

'Development Status :: 5 - Production/Stable'

,

'Operating System :: Microsoft :: Windows'

,

'Natural Language :: Chinese (Simplified)'

,

'Programming Language :: Python'

,

'Programming Language :: Python :: 2.7'

,

'Topic :: Software Development :: Libraries :: Python Modules'

], install_requires=[

'pyserial==3.2.1'

], )/<code>

然后打开setup.py所在目录,并将A和B两个文件夹复制过来

打开dos窗口,并运行

<code>

python

setup

.py

bdist_msi

/<code>

运行结果如下图:

build我们不关注,直接看dist,里面有一个Example-1.0.win32.msi,这就是我们生成的msi安装包。

我们再编写一个Example.py用来配置系统环境变量,并接受安装参数修改配置文件:

<code> 

import

os

import

sys

import

subprocess config_file =

r"C:\Python27\Lib\site-packages\B\lib\configuration\config.cfg"

import

sys

from

subprocess

import

check_call

if

sys.hexversion >

0x03000000

:

import

winreg

else

:

import

_winreg

as

winreg ENV_VARAIABLE =

'Result_Path'

class

Win32Environment

:

def

__init__

(self, scope)

:

assert

scope

in

(

'user'

,

'system'

) self.scope = scope

if

scope ==

'user'

: self.root = winreg.HKEY_CURRENT_USER self.subkey =

'Environment'

else

: self.root = winreg.HKEY_LOCAL_MACHINE self.subkey =

r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'

def

getenv

(self, name)

:

key = winreg.OpenKey(self.root, self.subkey,

0

, winreg.KEY_READ)

try

: value, _ = winreg.QueryValueEx(key, name)

except

WindowsError: value =

''

return

value

def

setenv

(self, name, value)

:

key = winreg.OpenKey(self.root, self.subkey,

0

, winreg.KEY_ALL_ACCESS) winreg.SetValueEx(key, name,

0

, winreg.REG_EXPAND_SZ, value) winreg.CloseKey(key)

try

: check_call(

'''\ "%s" -c "import win32api, win32con; assert win32api.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')"'''

% sys.executable)

except

Exception

as

e:

print

e.message

def

search_content

(str, lists)

:

""" 查找str是否存在于lists中,不存在就退出程序 """

for

i

in

lists:

if

str

in

i:

return

lists.index(i)

print

"The section not found"

os._exit(

1

)

def

run_command_line

(command_line)

:

""" 运行command line """

print(

"run:"

+ command_line) p = subprocess.Popen(command_line, shell=

True

, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (stdout, stderr) = p.communicate()

try

: print(

"stdout:"

+ stdout) print(

"stderr:"

+ stderr)

except

:

pass

def

main

()

:

run_command_line(

"msiexec /i "

+ sys.path[

0

] +

r"\Example-1.0.win32.msi /qb REBOOT=SUPPRESS"

) section = sys.argv[

1

] attribute = sys.argv[

2

] change = sys.argv[

3

] file = open(config_file,

'r'

) content = file.readlines() file.close() index = search_content(section, content) is_change =

False

for

change_str

in

content[index +

1

:]:

if

"["

in

change_str:

if

not

is_change:

print

"Property does not exist or not in this section"

break

if

attribute

in

change_str: content[content.index(change_str)] = change_str[:change_str.index(

"="

) +

1

] + change +

"\n"

is_change =

True

break

file = open(config_file,

'w'

)

for

i

in

content: file.write(i) file.close()

if

__name__ ==

"__main__"

:

if

len(sys.argv) ==

1

and

sys.argv[

0

] ==

"commonlib.exe"

: run_command_line(

"msiexec /i "

+ sys.path[

0

] +

r"\Example-1.0.win32.msi /qb REBOOT=SUPPRESS"

)

elif

len(sys.argv) !=

4

:

print

"Usage: commonlib.py

"

sys.exit(

1

)

else

: main() e = Win32Environment(scope=

"system"

) e.setenv(ENV_VARAIABLE,

r'C:\Local'

)

print

"Setup Success!"

/<code>

现在我们用Pyinstaller来进行最后的打包。

先看一个重要的文件Example.spec

spec文件是Pyinstaller打包成EXE的配置文件,是自动生成的,这里我直接拿以前的进行修改,刚开始没有的,可以直接随便运行一次Pyinstaller来获得,直接复制我的也可以。

<code> 
  
block_cipher = 

None

a = Analysis([

'Example.py'

], pathex=[

'C:\\Users\\abc\\Documents'

], binaries=

None

, datas=

None

, 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) a.datas+= [(

'Exmaple.msi'

,

r'C:\Users\abc\Documents\Example-1.0.win32.msi'

,

'DATA'

),] exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name=

'examlpe'

, debug=

False

, strip=

False

, upx=

True

, console=

True

)/<code>

打开Example.spec所在的路径,复制MSI安装包到这里,在dos窗口中运行

<code>`

pyinstaller

Example

.spec

/<code>

运行成功后,会生成build和dist两个文件夹,我们依然只看dist文件夹,里面example.exe就是我们所需要的

非常感谢你的阅读

大学的时候选择了自学python,工作了发现吃了计算机基础不好的亏,学历不行这是没办法的事,只能后天弥补,于是在编码之外开启了自己的逆袭之路,不断的学习python核心知识,

如果你处于想学python爬虫或者正在学习python爬虫,python爬虫的教程不少了吧,但是是最新的吗?
说不定你学了可能是两年前人家就学过的内容,在这小编分享一波2020最新的python爬虫全套教程最后小编为大家准备了3月份新出的python爬虫自学视频教程,免费分享给大家!
获取方式:私信小编 “ 资料分享 ”,即可免费获取!

\

简单三步!Python封装成可带参数的EXE安装包


简单三步!Python封装成可带参数的EXE安装包


分享到:


相關文章: