目录
1. 背景需求
有时候为了确保多平台的兼容性,需要开发绿色版的应用程序,也就是在嵌入式版Python上进行二次开发。并且工程目录中就包含源代码,方便随时开发和调试。
这个时候使用的启动器,实际上是文件夹内的一个Python解释器,那么可以很简单地使用一个 BAT
文件调用打开。
但是用户普遍对于 BAT
的接受程度不是很高,总是需要告诉用户运行哪个文件才能启动程序。
因为想要为 BAT
文件设置一个图标,只能创建一个快捷方式,然后修改快捷方式的图标。但是快捷方式嘛,拷贝到别的电脑里就没有用了。
这个时候如果设计一个带有图标的exe程序,那么岂不是一目了然,还能提升软件定位的档次。
这个软件的功能也非常简单,就是实现 BAT
文件的功能,使用文件夹内的Python解释器,打开文件夹内的一个Python脚本就可以了。然后再加上自己精致的图标。
2. 需求软件
3. 准备图标
应用程序窗口左上角的图标像素是 16×16 ,任务栏的图标是 24×24 ,文件夹浏览器里的图标最大可以支持 256×256 。
如果简单一点,可以使用 16 和 24 的最小公倍数,也就是按照 48×48 来设计图标。
将图片保存为支持透明颜色的 PNG
图像,然后用格式工厂转换成 ICO
格式,之后配合 windres
命令,就可以编译出包含有图标的exe可执行程序了。
4. 编译命令
如果你设计的是窗口程序,希望在运行程序时,不会有黑色的控制台窗口启动,需要进行下面三个设置,缺一不可。缺少一个都会导致黑窗仍然存在。
4.1 使用Windows API
使用 system(cmd)
可以最简单地模仿批处理程序运行一个命令,但是这个命令是通过 CMD
的管道执行的,所以必定会启动 CMD
的黑窗界面,效果是黑色窗口一闪而过。
所以为了避免这个问题,就要调用 Windows API 的 ShellExecuteA
函数了。
函数用法说明就不介绍了,网上可以自己查。
4.2 使用-mwindows参数编译
-mwindows
实际上是 -machine
和 windows
的合并,意思是生成包含窗口的应用程序,而非控制台程序。
我曾经以为这里的 windows
指的是“微软视窗系统”的“Windows”,但是实际上并不是。
就像常见的编译参数 -march
,并不是 march
这个单词三月的意思,而是 m
和 architecture
(构架)的合并。。
4.3 使用pythonw.exe解释器
pythonw
中的 w
又是 windows
的意思,是Python解释器中不启动控制台界面的版本。
所以想要启用Python脚本但是不会打开控制台界面,需要使用 pythonw
版本的解释器。
5. 测试运行
5.1 参考代码
需要准备5个文件:
- 测试被运行的Python文件
main.py
import wx
app = wx.App()
wx.MessageBox('Hello world!')
app.MainLoop()
- 主程序
main.c
#include <windows.h>
int main()
{
ShellExecuteA(NULL, "open", "bin\\pythonw.exe", "main.py", "src", SW_SHOW);
return 0;
}
- 图标
icon.ico
和资源文件icon.rc
101 ICON "icon.ico"
- 编译批处理文件
dist.bat
@echo off
windres icon.rc -o icon.o
gcc main.c icon.o -o main.exe -mwindows -s
upx main.exe
pause
双击运行 dist.bat
即可。
5.2 使用效果
使用效果是使用当前目录 bin
文件夹下的 pythonw.exe
文件,执行 src
文件夹中的 main.py
脚本。
运行效果: