Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как определить запущена ли моя программа  (Прочитано 20372 раз)
0 Пользователей и 1 Гость смотрят эту тему.
solowey
Гость
« : 19-02-2009 08:34 » 

Всем привет!
Я только начинаю изучать Dilphi.  А черт его знает...
Я запускаю программу. При повторном запуске той же программы хочу, чтобы появлялось окно с сообщением - Программа уже запущена. Как это можно релизовать?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 19-02-2009 10:31 » 

Примерно так (только тут на C++):

Код: (C++)
        if (FindWindow(NULL, PROGRAM_NAME) != NULL)
        {
            ShowMessage("Программа уже запущена!");
            return 0;
        }
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Basurman
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 19-02-2009 10:35 » 

В Windows API есть функция FindWindow, которая позволяет найти окно по имени класса или заголовку окна.
Разжёвывать не буду, лучше сам читай SDK. Оно полезней, и запомнится на дольше.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 19-02-2009 11:34 » 

Эммм... для этого необходимо чтобы имя главного окна программы было однозначным, чего в общем случае гарантировать нельзя.

Гораздо "чище" и сделать это через mutex. Как именно это делается в загадочном языке Dilphi не скажу, но help в помощь.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #4 : 19-02-2009 11:35 » 

а я бы создавал при старте именованный канал, если создать не получилось значит уже запущена Улыбаюсь
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #5 : 19-02-2009 11:52 » 

или именованный мутекс, я так сделал и оно давно работает Улыбаюсь В имя засунуть GUID
Записан

Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 19-02-2009 13:24 » 

Эммм... для этого необходимо чтобы имя главного окна программы было однозначным, чего в общем случае гарантировать нельзя.

Гораздо "чище" и сделать это через mutex. Как именно это делается в загадочном языке Dilphi не скажу, но help в помощь.
Присоединяюсь, я тоже через именованный мьютекс делал, когда мне нужно было решать такую задачу
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #7 : 19-02-2009 15:59 » 

Джон, в Delphi делается так же как и в VS. API Windows от языка и среды разработки не зависит.
Я тоже за мутекс.
Еще варианты: event, filemapping, атомы.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 19-02-2009 16:32 » 

Джон, в Delphi делается так же как и в VS.

А ну тогда вот так:

Определяем два мембера:

Код:
CSingleLock* m_SI_MyProg;
CMutex* m_Mutex_MyProg;


В конструкторе создаём и инициаллизируем объекты:

Код:
...
m_Mutex_MyProg  = new CMutex(FALSE,_T("MyProg_9B764182-8624-4EBF-8C76-066C07E1DB13"),NULL);
m_SI_MyProg = new CSingleLock(m_Mutex_MyPro);
...

В стартовую процедуру добавляем проверку:

Код:
...
if(!m_SI_MyProg->Lock(1))
{
TRACE0("Прожка уже запущена один раз. Этого хватит.\n");
return FALSE;
}

Не забываем удалить:

Код:
delete m_SI_MyProg;
delete m_Mutex_MyProg;
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #9 : 19-02-2009 17:11 » 

Код:
var
   hMutex: cardinal;

 hMutex:=CreateMutex(nil, false, '{CB166DD9-9657-458F-920D-EDD75AF8CF52}');
 If GetLastError<>0 then
 begin
  CloseHandle(hMutex);
  ShowMessage('Прога уже запущена!');
  exit;
 end;
CMutex - это уже MFC.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #10 : 19-02-2009 18:42 » 

Джон, new даже не надо , мона просто глобальную переменную, которую в InitInstance локнуть нужно (так сразу и определится, что уже есть экземпляр программы)
« Последнее редактирование: 19-02-2009 18:45 от Алексей1153++ » Записан

Basurman
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 19-02-2009 19:32 » 

Вариантов много.
Но используя FindWindow не по имени, а по классу окна всё-таки делается проще и без лишней загрузки системы.
Уж класс окна заранее известен и для окон приложений классы разные. В Delphi искать надо по классу главной формы, вот только при разработке программы надо немного поднапрячься и придумать что нибудь отличающееся от TForm1.
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #12 : 19-02-2009 20:13 » 

А если приложение вообще не имеет окна, да и называть главную форму по типу GUID как-то некошерно...
А создание мутекса загрузит систему примерно также, как муравей залезший на спину слона.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #13 : 19-02-2009 20:53 » 

А создание мутекса загрузит систему примерно также, как муравей залезший на спину слона.
да и проще во столько же раз Улыбаюсь Буквально - две строки

CMutex g_MyMTX(0,"имя");//глобальная переменная

//в инициализации приложения
if(!g_MyMTX.Lock())return 0;
Записан

zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #14 : 19-02-2009 21:00 » 

Алексей1153++, ну это с использованием MFC. В Delphi все таки на API надо делать.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 20-02-2009 09:39 » 

Но используя FindWindow не по имени, а по классу окна всё-таки делается проще и без лишней загрузки системы.

Чуть конктретней про загрузку системы мютексом. Чёт первый раз про такое слышу?

Цитата
придумать что нибудь отличающееся от TForm1.

Во-во.

для окон приложений классы разные

Вот два раза запустил одну и туже MFC-шную прожку спай++ показал два разных класса:

Afx:00400000:8:00010013:00000000:000203FB
Afx:00400000:8:00010013:00000000:002C0375

а это при запущеной второй, запустил параллельно её ещё раз, получил:

Afx:00400000:8:00010013:00000000:00010549

Джон, new даже не надо , мона просто глобальную переменную

А я ООП больше люблю. Ага

зы Забыл написать, собственно говоря, почему я CSingleLock стал использовать. На одной мультипроцной системе у юзверов всё-таки были проблемы при использовании только одного мютекса.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Basurman
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 21-02-2009 10:36 » 

Попробую отговориться на всё сразу.
А если приложение вообще не имеет окна, да и называть главную форму по типу GUID как-то некошерно...
А создание мутекса загрузит систему примерно также, как муравей залезший на спину слона.
Если приложение не имеет окна, это уже другой вариант.
Мутекс объект - ресурс системы. А ресурсы системы, мне кажется, лучше поберечь для действительно необходимых случаев. Муравей и слон конечно хорошо, но ведь была ещё и соломинка переломившая спину верблюду.
Насчёт названия класса формы - чем TZubrMainForm хуже TForm1?
Цитата от Джон: Вот два раза запустил одну и туже MFC-шную прожку спай++ показал два разных класса:".
А я пользуясь своим шпаем (в смысле - сам сочинил) для разных экземпляров одной и той-же программы получаю одинаковые имена и атомы классов их окон, а описатели окон, идентификаторы процессов и потоков разные.
Ну это всё уже около темы, а по теме:
В меню IDE Delphi: Project --> View Source.
И файл .dpr калечится примерно следующим образом:
Код:
program ProjectName;         {ProjectName = имя проекта}
uses
{здесь перечислены используемые модули}
{$R *.res}                   {это от папы Бормана, лучше не трогать}
Var
  CheckHandle : HWND;        {добавлены 2 строки - объявление переменной}
begin
  CheckHandle:=FindWindow(MainFormClassName, nil);   {найти окно главной формы приложения по классу}
  If CheckHandle<>0
    then                                             {окно найдено, уже запущен экземпляр приложения}
      begin
        If IsIconic(CheckHandle) then ShowWindow(CheckHandle, SW_RESTORE);  {если окно свёрнуто, восстановить}
SetForegroundWindow(CheckHandle);                                   {сделать активным окном переднего плана}
        {при нужде можно выдать сообщение типа: "Приложение уже запущено"}
      end
    else                                             {окно не найдено, можно запускать приложение}
      begin
        {Здесь операторы, которые были до изменения}
      end
end
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #17 : 21-02-2009 12:02 » 

Basurman, а где ты ещё мутексы часто используешь ? Улыбаюсь Или другие хендлы ? Думаю, ОДИН хендл на ОДИН экземпляр программы - простоты ради - святое дело.
Записан

Basurman
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 21-02-2009 14:28 » 

А разве в системе только одна моя программа крутится? Программ то много, и каждая норовит урвать побольше.
Вот запустил систему, открыл блокнот - уже 37 процессов запущено, причём половина из них ненужные.
Для интереса смотрю на SpeedFan - 21 окно верхнего уровня (top-level), не многовато ли для утилиты контролирующей температуру, частоту вращения вентиляторов и напряжения. Кстати тоже на Delphi VCL сделана, знакомые всё лица - TApplication, TForm1.
Раньше на компе стояла система, да видеоредактор. Захват видео шёл на ура, без пропусков кадров. А теперь пропускает только так.
Вообще то, это отдельная тема.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #19 : 21-02-2009 14:33 » 

Basurman, 37 процессов изза блокнота ? Да у вас, батенька вирусы... У меня - с блокнотом связан всего процесс и один ПОТОК.

Вирусы надо лечить
Записан

Basurman
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 21-02-2009 14:41 » 

Да нет, не из за блокнота. Acronics (стереть бы его, да лень), Catalyst, да прочая похабщина, такая как - сервис от Canon, сервис от Epson.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #21 : 21-02-2009 14:50 » 

Basurman, то есть система то плохо работает вовсе не изза программ, а изза бардака Ага  Если я поставлю в автозапуск 1000 безобидных блокнотов, думаю, что система тоже будет тормозить

А, заметь, сабж преследует цель не дать запустить более одного экземпляра программы
Записан

zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #22 : 21-02-2009 16:15 » 

Цитата
Раньше на компе стояла система, да видеоредактор. Захват видео шёл на ура, без пропусков кадров. А теперь пропускает только так.
У корректно-сделанного видеоредактора такого быть не должно. Если системе не хватает ресурсов, то должно тормозиться видео, но никак не пропуск кадров.
Записан
Basurman
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 24-02-2009 18:24 » 

О zubr, великий и ужасный, поделись секретом обучения курению видеомагнитофона и телевещания!!! Надо же им чем то заняться, пока комп с захватом тормозит.
А вообще ушли от темы. Надо с этим перемещаться.
Записан
Kivals
Команда клуба

us
Offline Offline
Пол: Мужской

WWW
« Ответ #24 : 24-02-2009 20:19 » 

Я тоже за mutex, хотя потом все равно искать окно, чтобы показать запущенный экземпляр.
Минус FindWindow: окно создается дольше, потому на загруженной системе если подряд запустить 2 экземпляра приложения, то запустятся оба, т.к. окно не найдет ни одна (пример - WinAmp 2.X: попробуйте на загруженной системе с установленной опцией "только 1 экземпляр" запустить несколько раз).
Код для Delphi (вставить в *.dpr):
Код:
...
const
  MutexApplicationName = '{Некий GUID}';
var
  HMutexApplication : THandle;
  LastErr : DWord;

begin // Это главный begin проекта
  HMutexApplication := CreateMutex(nil, FALSE, MutexApplicationName);
  // Неудача при создании - наверное приложение уже запущено
  if HMutexApplication=0 then begin
    LastErr := GetLastError;
    if LastErr=ERROR_ALREADY_EXISTS then begin
      // Здесь можно найти приложение по окну, но можно и не найти - см. выше
      Exit;
    end;
  end;
... // Все, что было раньше за begin

Для Delphi 5 нужно было в uses включить Windows. Для более поздних - не знаю.
Записан
DrGluck
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 12-03-2009 11:55 » 

Всю жисть такая задача через мьютекс решалась. Закрывайте тему.
Записан

Good user - dead user
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines