Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Общие вопросы _ Как определить запуск второго приложения ?

Автор: flankerr 3.6.2009, 15:39

Надо при запуске приложения определять есть ли уже запущанная копия(и) этого приложения.
Впрос как ?

Автор: Litkevich Yuriy 3.6.2009, 15:49

http://www.qtsoftware.com/products/appdev/add-on-products/catalog/4/Utilities/qtsingleapplication
Используется вместо QApplication или QCoreApplication

Автор: flankerr 3.6.2009, 16:08

QSingleApplication в Qt 4.3.3 что-то не нашёл.
Но судя из названия и из того что им надо заменить стандартный апликейшен можно сделать вывод что он не позволяет запускать копию. Тогда как мой вопрос звучал иначе,а имено
Как определить что уже запущена копия ?
т.е. мне НЕ нужно запрещать мне просто нужно в момент запуска знать есть ли уже запущенаая копия приложения

Автор: SABROG 3.6.2009, 16:23

bool QtSingleApplication::isRunning ()

Returns true if another instance of this application is running; otherwise false.

This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session).

Автор: Litkevich Yuriy 3.6.2009, 16:34

Цитата(flankerr @ 3.6.2009, 20:08) *
QSingleApplication в Qt 4.3.3 что-то не нашёл.
я тебе ссылку дал, раньше это было решение только для платников, теперь и под LGPL распространяется

Автор: flankerr 3.6.2009, 17:15

а чем платная версия отличается от свободной ?

Автор: Litkevich Yuriy 3.6.2009, 17:19

Цитата(flankerr @ 3.6.2009, 21:15) *
а чем платная версия отличается от свободной ?
лицензией

Автор: SABROG 3.6.2009, 17:19

Цитата(flankerr @ 3.6.2009, 18:15) *
а чем платная версия отличается от свободной ?

Тем, что раньше тебе надо было приобрести лицензию Qt, чтобы скачать этот класс и работать с ним или искать ворованную.

Если имеется ввиду то, что есть сейчас платная, так это также как с исходниками Qt. Если у тебя есть платная лицензия, то ты можешь изменять исходники Qt и исходники этого класса и продавать как собственную программу, иначе только использовать эти классы и продавать, но не изменять и продавать.

Автор: flankerr 3.6.2009, 17:35

но всё равно не понятно почему они отдельно выложили платную версию и отдельно свободную - если различия только в выше описанном тогда не понятно зачем разделять

Автор: SABROG 3.6.2009, 17:42

Там наверно в хедерах написано под какую они лицуху.

Автор: Litkevich Yuriy 3.6.2009, 17:49

Я видел, предыдущую версию комерческую, там просто к своему проекту подстёгиваешь исходники и компилируешь. В текущей наверное также.

LGPL не допускает статической линковки, следовательно надо сначало собрать dll'ку (so'шку). и её пользовать. В LGPL'ной версии есть всё необходимое для такой сборки.

Я думаю только в этом вся разница + примеры с соответствующим конкретной лицензии способом использования

Автор: flankerr 5.6.2009, 10:32

Посмотрел исходники и выяснилось два момента
1. под Qt 4.3.3 это дело собрать нельзя т.к. отсутсвуют QLocalSocket и QLocalServer которые появидлись в Qt 4.4
2. особого смысла в QSingleApplication нет т.к. проще самому без всяких лицензий и замены QtCore сделать это самому. Там как оказалось всё реализовано на старой идее с сокетами.

Автор: SABROG 5.6.2009, 10:45

Никто не пробовал реализовывать тоже самое, но на базе QSystemSemaphore или QSharedMemory?

Автор: flankerr 5.6.2009, 10:52

Вот создаёшь ты QSharedMemory. Пользователь по доброте душевной грохает твою прогу через удаление процеса и шара так и остаётся висеть до перезагрузки компа. Тоже касается и других системных именованых объектов.
Так что реализация определения запущенных копий подобными способами хотя и проста но не надёжна.

Автор: flankerr 5.6.2009, 13:46

Пока мутил с сокетами пришла в голову идея. Принцип действия как и через сокеты только вместо сокетов исползовать простой файл.

Прога запускается проверяет наличие файлика если его нет создаёт и прибавлет еденицу к счётчику записанному в файлик, а по выходу уменьшает счётчик и если он ноль удаляет файлик.

Воропс с убийством процеса решается добавлением в файлик метки времени.

Т.е. каждая копия программы ну скажем раз в минуту дёргает файл и обновляет метку времени. Если процесс убивается метка времени обновляться перестаёт и при следующем щапуске обнаружив файл прога смотрит метку времени если она слишком старая т.е. её время меньше на заданный промежуток чем текущие то данный файл считается недействительным и прога обнуляет счётчик.

Автор: SABROG 5.6.2009, 14:28

Цитата
Т.е. каждая копия программы

:blink: ты же вроде хотел, чтобы небыло копий программ?

Цитата
Если процесс убивается метка времени обновляться перестаёт

Да нет, таже программа, что проверяет метку должна была её обновить минуту назад, поэтому время всегда будет актуальным. А если таких программ 3, то какая из них упала вообще не представляется возможным понять. Это надо вводить какой-нибудь ID для программ, чтобы они могли свои метки идентифицировать и файл не с счетчиком, а со списком:

1244204575 rlipkalihu
1244204617 fxakstrqta
1244204624 grswkhxfjr


Соответственно, если запускается новая копия программы нужно генерить уникальный ID и добавлять его в конец с текущим timestampом, если программа завершается корректно, то строку со своим ID нужно удалять. Проблема может возникнуть при выключении или перезагрузки компьютера пользователем, когда все программы завершаются корректно. Все копии ломанутся записывать в этот файл и скорее всего удачно сделает это всего лишь одна копия, которая будет завершатся первой. А все остальные копии получат какой-нибудь access denied на файлик и ОС просто прихлопнет эти копии, т.к. они не успели завершится за отведенный промежуток времени.

Автор: flankerr 5.6.2009, 15:03

тут ты пошёл дальше :) Мне надо просто знать есть ли запущенные копии или нет. Т.е. вполне допускается ситуация когда работает несколько копий программы. Для этого вполне лдостаточно метки времени и счётчика. Каждая клпия раз в заданный промежуток обновляет метку времени что свидетельствует о валидность информации в файле.

Устанавливать каждому приложению уникальный номер слишком излишне. Тут нет задачи мониторить упало\не упало.

А вот одновременный доступ на запись из несольких приложений тут тонкое место... возможно шаредМемори болеее луший вариант но его нет в Qt 4.3.3 а переходить на более новые версии нельзя.

Автор: Sokoloff 5.6.2009, 15:25

А через список процессов нельзя определить есть запущенные копии? Да решение не кроссплатформенное, но IMHO самое прямое, или есть какие-то подводные камни?

Автор: Litkevich Yuriy 5.6.2009, 15:29

рекомендую на прогорге почитать ветку Константина, автора SingleApplication (не Qtишного), там много обсуждений о принципах работы, да и автора можно распросить поподробнее.

http://www.prog.org.ru/topic_7213_0.html

Автор: flankerr 8.6.2009, 16:46

Что то не понравился мне SingleApplication. Во первых он работает только под Qt 4.4 и выше. Во вторых юзает ШаредМемори. Спрашивается зачем тогда сокеты, а если есть сокеты то зачем ШаредМемори - в общем намудрил не понравилось.

Автор: BRE 8.6.2009, 17:24

Цитата(flankerr @ 8.6.2009, 17:46) *
Что то не понравился мне SingleApplication. Во первых он работает только под Qt 4.4 и выше. Во вторых юзает ШаредМемори. Спрашивается зачем тогда сокеты, а если есть сокеты то зачем ШаредМемори - в общем намудрил не понравилось.

Юра выше писал, автор SingleApplication известен, спроси у него для чего используется SharedMemory. Помниться, читал ветку посвященную этому компоненту, там вроде были какие-то косяки с сокетами на Mac'е.

Автор: flankerr 10.6.2009, 11:36

Повторюсь,если использовать шаредМемори то пропадает всякий смысл в сокетах.
Кстати недостатки описанной мной выше идеи с файлами убераються использованием ШаредМемори

Автор: Cergey 27.11.2009, 19:00

Добавлю сюда код с определением запуска через сокеты на WinAPI. Просто что-бы другие(и я) не искали после прочтения темы в гугле это.
HANDLE hnd = CreateMutex(NULL, TRUE, m_pszAppName);
if ( GetLastError() == ERROR_ALREADY_EXISTS && WAIT_ABANDONED != WaitForSingleObject(hnd, 1000))
{
AfxMessageBox("Application already running. ");
return FALSE;
}

Взято с http://forum.ixbt.com/topic.cgi?id=40:682

Стати для тех кто первый раз видит WinAPI
m_pszAppName - unicode строка
В QT для быстрого перевода можно использовать

QString text = "Lab 2 Server"; // Имя приложения
TCHAR* m_pszAppName = (TCHAR *)text.unicode(); // Имя в формате Unicode

Автор: Litkevich Yuriy 27.11.2009, 19:03

всё таки это всё какие-то извраты. Лучше использовать отлаженную кросплатформенную библиотеку от самих тролей.
Пока она была не доступна по LGPL, люди делали её аналог, и проверили кучу механизмов которые работали бы всюду. в Том числе и в многопользовательской среде.

Автор: Cergey 27.11.2009, 19:06

"Добавлю сюда код с определением запуска через сокеты на WinAPI"
Перепутал: не сокеты, а мьютексы!!!
Litkevich Yuriy, для быстрой сдачи пригодится.

Автор: SABROG 28.11.2009, 2:16

Цитата(Cergey @ 27.11.2009, 19:06) *
для быстрой сдачи пригодится.

Вот оказывается для чего программирование нужно, для быстрой сдачи! А я то дурак уже не учусь, а всё сдаю и сдаю из-за интереса...

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)