1 说下背景
有时会有这样一种场景,我写了个程序,该程序依赖一些第三方的动态库,假如现在将三方库放到了可执行文件同级目录下的dependence目录,现在我将程序打包好并发给了用户。此时用户是无法直接执行可执行程序的,因为找不到依赖的三方库文件。
有人会说了直接将三方库全部放到可执行文件同级目录下不就行了?
这样确实没问题,但是如果依赖的三方库特别多呢,统一放到dependence目录下分类管理岂不更好,不但结构清晰,维护起来也相对更容易。
此时又有人会说了,设置个环境变量不就可以了?
如果不嫌麻烦的话确实可以,我们的目标是用户无需做任何额外操作,直接就可以运行程序,尽可能不要让用户用着恶心。
2 举个例子
先提一下,Qt中主要使用qputenv函数来设置环境变量。
bool qputenv(const char *varName, const QByteArray &value)
这里假如有个程序叫target.exe,它依赖的dependence目录下的三方库,需要注意的是,target.exe程序里面设置环境变量是不行的,因为程序运行前就需要知道依赖的三方库。
这时需要写另一个程序,这里假如叫launch.exe,来为target.exe设置环境变量并启动它,launch.exe此时的不仅可以管理target.exe的环境变量,还能够管理其生命周期。代码如下:
#include <QApplication>
#include <QProcess>
#include <QDir>
void initializeEnv();
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
initializeEnv();
QProcess process;
QObject::connect(&process, QOverload<int>::of(&QProcess::finished), &a, &QApplication::quit);
process.start("target.exe");
return a.exec();
}
void initializeEnv()
{
QString envPath = qgetenv("PATH");
QString appDirPath = QApplication::applicationDirPath();
QString dependencePath = appDirPath + "/dependence";
envPath += QDir::toNativeSeparators(dependencePath).prepend(';');
qputenv("PATH", envPath.toStdString().c_str());
}
这样通过运行launch.exe来间接运行target.exe后,target.exe便拥有了指定的环境变量。
3 对比一下
直接运行target.exe,打印结果如下:
通过launch.exe间接运行target.exe,打印结果如下:
结果是特别显然的,这时就不用去手动配置环境变量了,直接就可以运行,用户体验棒棒的。