Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Следить за приложением, при помощи службы 
:(
    Опции темы
Лена
Дата 12.6.2008, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Как известно служба Windows может управлять работай другой службой. В качестве примера можно взять две службы: InterBase Guardian и InterBase Server.
InterBase Guardian следит за тем, чтобы InterBase Server все время работал и если что-то случиться и InterBase Server остановиться, то InterBase Guardian его перезапустить снова.
Я хочу написать службу, которая следила за тем, что запущенна ли нужная мне программа Win32 и если она не запущена запустить ее. Т.е. добиться того чтобы нужная мне программа работала постоянно. 
Предполагаю, что нужно в службе, которая будет следить за моим приложением Win32 следующее:
1. При старте системы убедиться, что Windows полностью загрузился.
2. Найти окно моего приложения и если его нет, то запустить программу.
Исходя из этого такой код:
Согласно документации в коде службы строкой if(FindWindow("Progman", 0)) можно убедиться, что Windows полностью загружен, т.к. класс Progman это скрытое окно Explorer.exe. Если Explorer.exe загружен, то все ОК.
Значит примерно так:
Код

//основной поток службы
void _fastcall ИмяСлужбы::ServiceExecute(TService *Sender)
{
try
{
//цикл службы 
while(!Terminated) 
  {
   //если Windows полность загрузился
    if(FindWindow("Progman", 0))
    {
     //начать поиск нужной мне программы  Win32
     if(!FindWindow("Класс нужной мне программы", 0))
      {
      //запустить нужную программу через ShelExucate
      }

    }
   ServiceThread->ProcessReguests(false);
  }
}
catch(...)
  {
   //записать в журнал Windows о сбое
   ИмяСлужбы->LogMessage(...);
  }
}


Правилен ли такой подход? Может контроль за работой приложения надо организовывать иначе?


PM MAIL   Вверх
rrrFer
Дата 12.6.2008, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 208
Регистрация: 11.5.2008
Где: Красноярск

Репутация: нет
Всего: 1



Лена, 
Цитата(Лена @  12.6.2008,  10:01 Найти цитируемый пост)
 Может контроль за работой приложения надо организовывать иначе?

можно использовать cmd tasklist , cmd find и cmd start. ,наверно. 
    То-есть программа должна добавить себя в очередь при загрузке: cmd schtasks onlogon
    Затем вывести все запущенные в системе процессы cmd tasklist
    выполнить поиск, по имени, в этом списке, для этого проще всего использовать >> для вывода списка в файл, а потом, этот файл передать в cmd find, и если процесс еще не запущен, то выполнить cmd start
   потом программа должна "уснуть" на какое то время, например минуту - можно помучаться с функцией Sleep(помучаться, потом-что она работает, пока на ваще приложение установлен фокус ввода) или о5 же использовать планировщик(поставить программу в очередь
cmd schtasks /create ... /sc minute /mo 1 а затем "убить" работающий процесс cmd taskkill). Подходит/нет?
PM MAIL WWW ICQ   Вверх
Rrader
  Дата 12.6.2008, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 13
Всего: 191



Если есть окно, то, в принципе, нормальный подход smile Хотя можно использовать объекты синхронизации Windows (Event, Mutual exception). Более универсальные, и позволяют без окон определять наличие запущенного приложения. Еще есть глобальные атомы  smile Смотрите, что для Вас лучше smile 


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Лена
Дата 12.6.2008, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



Цитата(Rrader @  12.6.2008,  13:50 Найти цитируемый пост)
 Смотрите, что для Вас лучше 


Для меня лучше, то что будет более надежным. smile 
Атомы – это хранящаяся в Windows таблица строк, как их можно применить в моем случае?

Мне нужна гарантия, что это приложение будет работать постоянно, чтобы пользователь даже если закрыл его или произошел перезагруз компьютера, или процесс сам случайно закрылся, приложенее могло сново само запуститься.
Планируется что это приложение будет принимать данные от приборов через порт по пртокололу TCP/IP и складывать их в базу данных. 
Можно было бы оформить само это приложение слушающее порт в виде службы. Но это приложение будет постоянно модифицироватся, будут добовляться новые типы приборов. Поэтому гораздо легче переделывать приложение Win32 и отдовать его, чем переделывать службу и заботиться о последующей ее инсталяции.
Двумя словами так:
1. Нужна программа слушающая порт и периодически код программы будет меняться. Чтобы облегчить задачу хочу просто приложение Win32. (Можно формить код слушания порта в виде DLL, но опять возникает проблема написания устойчивой, постоянно работающей программы вызывающей этот код DLL).
2. Нужно чтобы это приложение постоянно работало.

Поэтому думала так: простое в распостранении приложение exe (которое можно быстро менять и отдавать без доп. инсталяции), которое отдается пользователю в нужную папку и служба (единожды проинсталированная у пользователя на сервере). Служба просто для гарантии - следить за работой программы слушающей порт... 

P.S.
Попутно переделала код службы.
Чтобы служба не работала быстро как электро веник, сделала задержку.  smile 
Ище для служб важно предусмотреть все возможные исключения.
Вот этот вариант пригоден?
Код

//--------------------------------------------------------
//основной поток службы
void _fastcall ИмяСлужбы::ServiceExecute(TService *Sender)
{
try
{
//цикл службы 
while(!Terminated) 
  {
   //если Windows полность загрузился
    if(FindWindow("Progman", 0))
    {
      //начать поиск нужной мне программы  Win32
      if(!FindWindow("Класс нужной мне программы", 0))
      {
      try
         {
         //запустить нужную программу через ShellExucate
         }
          catch(...)
                  {
                  //записать в журнал Windows о сбое
                  ИмяСлужбы->LogMessage(...); //описать проблему ShellExucate
                  }
      }
    }
    //пусть служба делает свою работу с перерывом в 5 секунд
    Sleep(5000);
    ServiceThread->ProcessReguests(false);
  }
}
catch(...)
  {
   //записать в журнал Windows о сбое
   ИмяСлужбы->LogMessage(...);//описать проблему потока службы
  }
}
//--------------------------------------------------------





PM MAIL   Вверх
Rrader
  Дата 12.6.2008, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 13
Всего: 191



Делайте Sleep в начале цикла. Задержку можно поставить поменьше smile 

Если Вы уверены, что класс окна приложения, за которым ведется слежка, уникален, то вариант пригоден. Если есть опасения, что класс будет неуникальным, то можно воспользоваться EnumWindows, а там при нахождении нужного окна еще и дополнительную проверку проводить. Например, послать собщение (задав желаемую реакцию в приложении), проверить свойство и т.п.

Более надежны мьютексы. Или события...
Код

HANDLE hMutex = CreateMutex(NULL, true, "ObscureText");
if (GetLastError()) {
    // Приложение запущено
    MessageBox(0, "Running instance has been detected!", "Error", 0);             
}        
else {
    // Уничтожаем мьютекс
    ReleaseMutex(hMutex);
    // Запускаем приложение (а в нём в это время создается мьютекс)
     ...
}

Но мьютексы имеют недостаток - ресурсоемки и требуют самостоятельный запуск приложения для надежности. Но, как я понял, специфика Вашей задачи как раз подразумевает автоматический запуск приложения. Т.е. метод пригоден smile

Это сообщение отредактировал(а) Rrader - 12.6.2008, 15:02


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
Лена
Дата 12.6.2008, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 879
Регистрация: 16.8.2006

Репутация: 11
Всего: 11



>Если Вы уверены, что класс окна приложения, за которым ведется слежка, уникален, то вариант пригоден.

Поскольку я сама разрабатываю приложение, то думаю, что класс окна будет уникален. smile 

Если явных просчетов в коде моей службы, который я привела выше нет, то буду пробывать свой вариант. smile 
Спасибо за помощь!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0487 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.