我想将我的应用程序作为单个实例执行,目前我正在使用QSharedMemory
并且正常工作。我在Ubuntu 12.04上使用Qt5.2.1。
以下是我的测试代码:
QApplication a(argc, argv);
a.processEvents();
const char* MEM_KEY = "56";
QSharedMemory sharedMem(MEM_KEY);
if( !sharedMem.create( 512, QSharedMemory::ReadWrite) )
{
QMessageBox msgBox;
msgBox.setText( QObject::tr("Can't start more than one instance of the application.") );
msgBox.setIcon( QMessageBox::Critical );
msgBox.exec();
exit(0);
}
MainWindow w;
w.show();
int p=0;
//p=p/0; // create exception here
return a.exec();
但是if
使应用程序崩溃(如上面的代码所示)。如果我再次启动应用程序,它会显示Can't start more than one instance of the application
,这意味着前一个实例即使崩溃也仍然存在。在我的情况下不应该发生这种情况。
如何在这种情况下重启我的应用程序?
修改
实际上我的原始项目包含很多源文件(上面的文件仅用于测试)。我想在我的原始项目上实现它,编辑最少的源文件,如果可能的话,只需编辑main.cpp
答案 0 :(得分:3)
您可以使用QSetting:
int main(int argc, char *argv[])
{
QSettings settings;
QApplication a(argc, argv);
if(!settings.exitedNormaly()) {
// In case of crash
}
// set the flag to false
settings.setExitedNormaly(false);
MainWindow w(&settings);
w.processArg(argc, argv);
w.show();
int result = a.exec();
settings.setExitedNormaly(result == 0);
return result;
}
结合您的共享内存,您可以在应用程序崩溃的情况下解锁该块。
答案 1 :(得分:1)
for linux:
// ----------------------------------
QProcess *m_prSystemCall;
m_prSystemCall = new QProcess();
QString Commnd = "pgrep " + qApp->applicationDisplayName();
m_prSystemCall->start(Commnd);
m_prSystemCall->waitForFinished(8000);
QString output(m_prSystemCall->readAllStandardOutput());
QStringList AppList = output.split("\n", QString::SkipEmptyParts);
qDebug() <<"pgrep out:"<<AppList;
for(int i=0;i<AppList.size()-1;i++)
{
Commnd = "kill " + AppList.at(i);
m_prSystemCall->start(Commnd);
m_prSystemCall->waitForFinished(8000);
}
// --------------------------------------------- ----------
和Windows:
#include <tlhelp32.h>
#include <comdef.h>
QString pName = qApp->applicationDisplayName();
pName += ".exe";
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE)
{
DWORD myPID = GetCurrentProcessId();
while (Process32Next(snapshot, &entry) == TRUE)
{
const WCHAR* wc = entry.szExeFile ;
_bstr_t b(wc);
const char* c = b;
if (stricmp(c, pName.toStdString().c_str()) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
qDebug() <<"myPID: "<< myPID << "entry.th32ProcessID" << entry.th32ProcessID;
if(myPID != entry.th32ProcessID)
TerminateProcess(hProcess,0);
QThread::msleep(10);
CloseHandle(hProcess);
}
}
}
CloseHandle(snapshot);