Seite 1 von 1

SingleApplication (Linux only)

Verfasst: 25. Dezember 2007 07:16
von Burgpflanze
singleapplication.h

Code: Alles auswählen

/***************************************************************************
 *   Copyright (C) 2007 by Peter Gaede   *
 *   develop@linux-peter.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef SINGLEAPPLICATION_H
#define SINGLEAPPLICATION_H

#include <QApplication>

class SingleApplication : public QApplication
{
	Q_OBJECT

	public:
		SingleApplication(const QString &lockFile, int &argc, char **argv);
		~SingleApplication();

		bool isRunning() const;
		QString lockFile() const;

	private:
		bool m_isRunning;
		QString m_lockFile;
		
		bool checkForRunningInstance();
};

#endif // SINGLEAPPLICATION_H
singleapplication.cpp

Code: Alles auswählen

/***************************************************************************
 *   Copyright (C) 2007 by Peter Gaede   *
 *   develop@linux-peter.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "singleapplication.h"
#include <QFile>
#include <QProcess>
#include <QWidget>
#include <QMessageBox>
#include <QDir>
#include <unistd.h>

SingleApplication::SingleApplication(const QString &lockFile, int &argc, char **argv)
	: QApplication(argc, argv)
{
	m_lockFile = QString("%1/%2").arg(QDir::tempPath()).arg(lockFile);
	m_isRunning = checkForRunningInstance();
}

SingleApplication::~SingleApplication()
{
	if (!m_isRunning)
	{
		QFile file(m_lockFile);
		if (file.exists())
			file.remove();
	}
}

bool SingleApplication::checkForRunningInstance()
{
	QFile file(m_lockFile);

	// Check if lock file exists
	if (file.exists())
	{
		// Now we check if a previous instance are running
		if (file.open(QIODevice::Text | QIODevice::ReadOnly))
		{
			QString pid = QString(file.readLine());
			file.close();

			if (!pid.isEmpty())
			{
				QProcess p;

				p.start("ps", QStringList() << "--pid" << pid);
				p.waitForFinished();

				QString data = QString(p.readAllStandardOutput());
				if (data.contains(pid))
					return true;
			}
		}
		else
		{
			QWidget w;
			QMessageBox::critical(&w, tr("Lock file error"), QString(tr("Unable to open lock file for reading:\n%1")).arg(m_lockFile));
			return true;
		}
	}

	// We are the only one instance, now we write our pid to lock file
	if (file.open(QIODevice::Text | QIODevice::WriteOnly))
	{
		file.resize(0);
		file.write(QString::number(getpid()).toAscii());
		file.close();
	}
	else
	{
		QWidget w;
		QMessageBox::critical(&w, tr("Lock file error"), QString(tr("Unable open lock file for writing:\n%1")).arg(m_lockFile));
		return true;
	}

	return false;
}

QString SingleApplication::lockFile() const
{
	return m_lockFile;
}

bool SingleApplication::isRunning() const
{
	return m_isRunning;
}
test.cpp

Code: Alles auswählen

#include "singleapplication.h"
#include <QDialog>

int main(int argc, char **argv)
{
	SingleApplication app(".singleapptest_lock", argc, argv);
	if (app.isRunning())
		return 0;
    
    QDialog d;
    d.show();

    app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
    return app.exec();
}

Verfasst: 6. April 2010 01:33
von hakaishi
Um zu überprüfen, ob ein Programm schon läuft ist das sehr viel Code...
Mit QDBus kann ich das auf eine if-Schleife in main.cpp reduzieren:

Code: Alles auswählen

int main(int argc, char *argv[]){

  QApplication app(argc, argv);

  SomeClass window;

  if(QDBusConnection::sessionBus().registerService("org.example")){
    window.show();
    return app.exec();
  }
}
Nicht zu vergessen "QT += dbus" in der .pro Datei hinzuzufügen.

Wer möchte kann jetzt nach der if(...) ein else anhängen, wo man eine QMessageBox erzeugen und anzeigen lassen kann.
Man kann auch das laufende Programm anzeigen lassen, aber das ist dann schon komplexer. Wer wissen will wie das geht, kann sich bei http://doc.trolltech.com/4.5/qtdbus.html erkundigen, oder mein Programm qshutdown ansehen (wegen der Windows Kompatibilität ist es allerdings etwas unübersichtlich geworden, da es QDBus unter Windows nicht gibt).

Gruß, Hakaishi

Verfasst: 6. April 2010 15:35
von Christian81
Oder noch einfacher mit der Qt-Solution 'QtSingleApplication' :)

Verfasst: 6. April 2010 17:31
von hakaishi
Christian81 hat geschrieben:Oder noch einfacher mit der Qt-Solution 'QtSingleApplication' :)
http://doc.trolltech.com/solutions/3/qt ... ation.html
Sieht zwar einfacher aus, als das obige Bsp., aber ich finde mit QDBus ist das genauso leicht umzusetzten... - Allerdings wird QDBus von Windows nicht unterstützt...