最近有一个小项目,有如下的需求:
将某几个源码文件夹进行打包,文件夹内有py文件、dll文件、exe文件等各种文件类型
打包生成的安装包,在进行安装的时候,应该能够带有参数,对配置文件进行修改配置
安装过程中,可以配置系统环境变量
能够检测环境,提示安装依赖包
整个过程要可以自动化,能够大量部署
综合考虑后,决定以下几个步骤完成:
用setup.py将源码文件夹都打包成msi安装包,这样可以使用msiexec进行静默安装
setup.py可以提示用户安装依赖包,否则安装失败
再编写一个py文件,用来静默安装msi安装包,并配置系统环境变量,接受安装参数去修改配置文件的属性
最后使用pyinstaller将所有都打包成exe文件
先来编写setup.py文件:
<code>from
distutils.coreimport
setupimport
osdef
get_all_dir
(path)
:""" 获取指定路径下的所有文件 """
all_file = []for
dirpath, dirnames, filenamesin
os.walk(path):for
filenamein
filenames: all_file.append(dirpath)return
all_fileif
__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
osimport
sysimport
subprocess config_file =r"C:\Python27\Lib\site-packages\B\lib\configuration\config.cfg"
import
sysfrom
subprocessimport
check_callif
sys.hexversion >0x03000000
:import
winregelse
:import
_winregas
winreg ENV_VARAIABLE ='Result_Path'
class
Win32Environment
:def
__init__
(self, scope)
:assert
scopein
('user'
,'system'
) self.scope = scopeif
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
valuedef
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
Exceptionas
e:def
search_content
(str, lists)
:""" 查找str是否存在于lists中,不存在就退出程序 """
for
iin
lists:if
strin
i:return
lists.index(i)"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_strin
content[index +1
:]:if
"["
in
change_str:if
not
is_change:"Property does not exist or not in this section"
break
if
attributein
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
iin
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
:"Usage: commonlib.py
"
sys.exit(1
)else
: main() e = Win32Environment(scope="system"
) e.setenv(ENV_VARAIABLE,r'C:\Local'
)"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爬虫自学视频教程,免费分享给大家!
获取方式:私信小编 “ 资料分享 ”,即可免费获取!
\