赞
踩
由于NSIS实现自定义界面,以及把安装包和升级包合并太过复杂,在各种尝试失败之后决定自己写安装包和卸载包。
原本项目中已经有一个让程序只运行一次的代码,使用QSystemSemaphore和QSharedMemory实现的。
- QSystemSemaphore sema("Key",1,QSystemSemaphore::Open);
- sema.acquire();//在临界区操作共享内存 SharedMemory
- QSharedMemory mem("Object");//全局对象名
- if (!mem.create(1))//如果全局对象以存在则退出
- {
- NDialog dialog(QApplication::focusWidget());
- NMessageBox Msg(&dialog,NMessageBox::ErrMsg,QObject::tr("软件运行中,再次打开前请先关闭。"));//获取最后一条错误信息
- dialog.setWidget(&Msg,QObject::tr("软件打开错误"));
- dialog.exec();
- sema.release();
- return 0;
- }
- sema.release();
但后来发现,这段代码只支持同时运行两个程序,当第三个程序运行时,只会在后台出现,不会有任何界面提示,即使把前两个程序关闭也不行。直到打开任务管理器,把所有程序全部结束掉,再打开才能正常使用。
这种场景在日常使用并不常见,但是如果加入安装/卸载程序,三种程序都用这种方式,出现的概率就大很多,于是引入QtSingleApplication。
由于使用pri文件方式在修改代码时出现了问题(也可能是配置问题),实在懒得深究了,就直接把代码添加到目录里面了。
- win32 {
- SOURCES += qtlockedfile/qtlockedfile_win.cpp
- }
- unix {
- SOURCES +=qtlockedfile/qtlockedfile_unix.cpp
- }
- #include <QApplication>
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- NUninstallDialog w;
- w.show();
- return a.exec();
- }
改为
- #include "qtsingleapplication/qtsingleapplication.h"
- int main(int argc, char *argv[])
- {
- QtSingleApplication a(QLatin1String("UninstallId"),argc, argv);
- if(a.isRunning())
- {
- NMessageDialog dialog(QApplication::focusWidget());
- dialog.setText(false,QObject::tr("有相同Uninstall卸载程序正在运行,再次打开前请先关闭。"));
- dialog.exec();
- return 1;
- }
- NUninstallDialog w;
- w.show();
- return a.exec();
- }
这样修改后,打开多少个程序,就会出现多少提示框,不会有程序在后台不出现的情况了。
如果仅仅是解决打开多个程序,以上代码就能满足要求。但由于项目是需要同时检测安装包、卸载包、执行文件的,除了它们自己本身需要只允许一次以外,还需要这三个程序只能运行其中一个。
由于QtSingleApplication是继承QApplication的,而QT程序只允许有一个QApplication类。因此需要在QtSingleApplication中添加一个独立查询AppId的函数。
- //QtSingleApplication.h
- bool isAppIdRuning(const QString &appId);
- //QtSingleApplication.cpp
- bool QtSingleApplication::isAppIdRuning(const QString &appId)
- {
- QtLocalPeer lpeer(this, appId);
- return lpeer.isClient();
- }
- int main(int argc, char *argv[])
- {
- QtSingleApplication a(QLatin1String("UninstallId"),argc, argv);
-
- if(a.isRunning())
- {
- NMessageDialog dialog(QApplication::focusWidget());
- dialog.setText(false,QObject::tr("有相同Uninstall卸载程序正在运行,再次打开前请先关闭。"));
- dialog.exec();
- return 1;
- }
-
- if(a.isAppIdRuning("SetupId"))
- {
- NMessageDialog dialog(QApplication::focusWidget());
- dialog.setText(false,QObject::tr("Setup.exe安装程序正在运行,请关闭后再打开本卸载程序。"));
- dialog.exec();
- return 1;
- }
-
- if(a.isAppIdRuning("xxxId"))
- {
- NMessageDialog dialog(QApplication::focusWidget());
- dialog.setText(true,QObject::tr("xxx.exe运行中,是否强行关闭?"));
- if(dialog.exec() != QDialog::Accepted)
- {
- return 1;
- }
- }
-
- NUninstallDialog w;
- w.show();
- return a.exec();
- }

做安装包和卸载包其实还有几个问题没有攻克,只是这个刚好做起来有点麻烦,所以记录一下。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。