Russian Qt Forum

Qt => Общие вопросы => Тема начата: EverGreen от Ноябрь 02, 2009, 20:21



Название: как предотвратить запуск двух экземпляров приложения
Отправлено: EverGreen от Ноябрь 02, 2009, 20:21
Знаю ,тема избита , но поиском не нашел. Может в Qt есть какое то готовое решения этой проблемы ?


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: BRE от Ноябрь 02, 2009, 20:23
Поищи на форуме QSingleApplication


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: lit-uriy от Ноябрь 02, 2009, 20:24
Qt Solution (http://qt.nokia.com/products/appdev/add-on-products/catalog/4) - QtSingleApplication


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: Joss от Ноябрь 02, 2009, 23:54
Код:
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QSharedMemory sharedMemory("appname");
    if (!(sharedMemory.create(1) && sharedMemory.error() != QSharedMemory::AlreadyExists)) {
        exit(1);
    }
    ....
}


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: EverGreen от Ноябрь 04, 2009, 17:18
Спасибо всем за советы , но
- вариант с QtSingleApplication не катит тем , что этот класс нужно скачивать и распостранять вместе с приложением в   виде  либы или просто вставлять эти файлы в проект .
- вариант  с shared memory хорош, но как с ним работать дальше. Мне нужно поднять существующее окно приложения .
  Получается я должен, как то найти сторонее окно и его поднять?
  Может еще какие варианты есть ? ???


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: SABROG от Ноябрь 04, 2009, 17:54
По-хорошему алгоритм должен быть следующим:

- определили, что программа уже запущена
- шлем ей сообщение типа "всплывай давай"
- программа обязательно должна ответить что-то типа "хорошо, щас всплыву"
- если этого ответа не последовало в течении определенного времени, значит это не наша программа, либо она зависла, либо занята, либо она вообще не запущена, а sharedmemory остался висеть после краша программы и будет висеть до перезапуска ОС (в случае с windows).

Идеального решения не существует.


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: lit-uriy от Ноябрь 04, 2009, 18:16
>>в случае с windows
В доке по Qt написано обратное, виндовоз всегда убивает экземпляр общей памяти если она больше ни кем не используется, в отличие от линя:

Цитировать
When using this class, be aware of the following platform differences:
  • Windows: QSharedMemory does not "own" the shared memory segment. When all threads or processes that have an instance of QSharedMemory attached to a particular shared memory segment have either destroyed their instance of QSharedMemory or exited, the Windows kernel releases the shared memory segment automatically.
  • Unix: QSharedMemory "owns" the shared memory segment. When the last thread or process that has an instance of QSharedMemory attached to a particular shared memory segment detaches from the segment by destroying its instance of QSharedMemory, the Unix kernel release the shared memory segment. But if that last thread or process crashes without running the QSharedMemory destructor, the shared memory segment survives the crash.
  • HP-UX: Only one attach to a shared memory segment is allowed per process. This means that QSharedMemory should not be used across multiple threads in the same process in HP-UX.


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: lit-uriy от Ноябрь 04, 2009, 18:17
этот класс нужно скачивать и распостранять вместе с приложением в   виде  либы или просто вставлять эти файлы в проект .
что в этом такого?


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: SABROG от Ноябрь 04, 2009, 18:21
Перепутал, но общей картины это не меняет. В винде тоже приложения часто остаются висеть в памяти, причем без каких либо окон, а ответа так от них можно вечность ждать. Тот же firefox с excel приходится часто убивать, т.к. они находят себя в памяти. Уж лучше написать приложение, которой могло бы работать в любом количестве экземпляров, а то "секретарши" достали дергать сисадминов, чтобы тот убил им процесс, т.к. понимаешь годовой отчет не хочет открываться.


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: SASA от Ноябрь 04, 2009, 19:38
- шлем ей сообщение типа "всплывай давай"
- программа обязательно должна ответить что-то типа "хорошо, щас всплыву"

А как?


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: Igors от Ноябрь 04, 2009, 20:17
- вариант  с shared memory хорош, но как с ним работать дальше. Мне нужно поднять существующее окно приложения .
  Получается я должен, как то найти сторонее окно и его поднять?
  Может еще какие варианты есть ? ???

На Вындоуз я боролся так
Код:
 
bool MyApp::StopSecondInstance(const char * appTitle)
{
    mMutex = ::CreateMutex(NULL, TRUE, mCaption);
    if (GetLastError() != ERROR_ALREADY_EXISTS) return false;

// now returned value is a handle to other creator thus it should not be deleted, set it 0
    mMutex = 0;

// activate previous instance
    HWND wnd = FindWindow(mFrameClass, appTitle);
    if (wnd) {
if (IsIconic(wnd)) ShowWindow(wnd, SW_RESTORE);
SetForegroundWindow(wnd);
    }
    return true;
}
Ну и мочить mMutex в деструкторе


Название: Re: как предотвратить запуск двух экземпляров приложения
Отправлено: break от Ноябрь 11, 2009, 02:35
этот класс нужно скачивать и распостранять вместе с приложением в   виде  либы или просто вставлять эти файлы в проект .
что в этом такого?


Честно говоря тоже убило - неужели изобрести свой велосипед - разобравшись с двумя нативными способами и потом все равно "распостранять вместе с приложением в   виде  либы или просто вставлять эти файлы в проект" --- может оказаться проще?