Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Резидентный будильник


Автор: Mikel47 23.9.2004, 16:02
Как сделать программу резидентной?
И резидентная программа - значит ли это, что она должна быть свернута в трей?
Всем заранее спасибо

Автор: NiJazz 23.9.2004, 16:24
Mikel47
Пиши как службу.
Выложу пример. Написано мною, давно. Главную функцию назови как тебе удобно, но не забудь сделать изменения в списке аргументов CreateThread.
Код
//////////////////////////////////////////////////////////////////////////
#include <iostream.h>
#include <windows.h>
#include <string.h>
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
#define TOTAL_GROUPS    4

#define ARGS_IN_LIST    2

#define NUMBER_OF_SID    0
#define CURRENT_ACCESS_MASK   1

#define IS_ADMIN     0
#define IS_USER      1
#define IS_GUEST     2
#define IS_POWER_USER    3
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Глобальные переменные
SERVICE_STATUS   ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
HANDLE     hPipe;
PACL     pAcl = NULL;
HANDLE     hThread;
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Основная работа службы
DWORD WINAPI PlayWithFile(void *)
{
// Твоя функция
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Функция управления службой
VOID __stdcall CtrlHandler (DWORD Opcode)
{    
//////////////////////////////////////////////////////////////////////////
switch(Opcode)    
{        
case SERVICE_CONTROL_PAUSE:
  // Пауза
           ServiceStatus.dwCurrentState = SERVICE_PAUSED;
  break;
   case SERVICE_CONTROL_CONTINUE:
  // Play
           ServiceStatus.dwCurrentState = SERVICE_RUNNING;
  break;
  // Стоп
case SERVICE_CONTROL_STOP:
           ServiceStatus.dwWin32ExitCode = 0;
           ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
           ServiceStatus.dwCheckPoint    = 0;
           ServiceStatus.dwWaitHint      = 0;  
 
  //////////////////////////////////////////////////////////////////////////
  // Задаём SERVICE_STATUS
           if (!SetServiceStatus(
      ServiceStatusHandle,
      &ServiceStatus))            
  {
               cout << "Couldn't set service status: " << GetLastError() << endl;
           }  
  return;          

 case SERVICE_CONTROL_INTERROGATE:
         break;  
}      
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// Задаём SERVICE_STATUS
   if (!SetServiceStatus (ServiceStatusHandle,  &ServiceStatus))    
{
       cout << "Couldn't set service status: " << GetLastError() << endl;        
}    
//////////////////////////////////////////////////////////////////////////

return;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
// Функция работы службы
void __stdcall ServiceWork(DWORD argc, LPTSTR *argv)
{
//////////////////////////////////////////////////////////////////////////
// Переменные
DWORD status;
DWORD specificError;
//////////////////////////////////////////////////////////////////////////

ServiceStatus.dwServiceType    = SERVICE_WIN32;
   ServiceStatus.dwCurrentState      = SERVICE_START_PENDING;
   ServiceStatus.dwControlsAccepted  = SERVICE_ACCEPT_STOP |
            SERVICE_ACCEPT_PAUSE_CONTINUE;
   ServiceStatus.dwWin32ExitCode   = 0;
   ServiceStatus.dwServiceSpecificExitCode = 0;
   ServiceStatus.dwCheckPoint    = 0;
   ServiceStatus.dwWaitHint    = 0;  

   //////////////////////////////////////////////////////////////////////////
   ServiceStatusHandle = RegisterServiceCtrlHandler(
          TEXT("Service1"),
          CtrlHandler);
// Если не смог
if (ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)    
{
       cout << "Couldn't register service's control handler: " << GetLastError() << endl;
 return;    
}  
//////////////////////////////////////////////////////////////////////////

   status = NO_ERROR;
   
if (status != NO_ERROR)    
{
       ServiceStatus.dwCurrentState       = SERVICE_STOPPED;
       ServiceStatus.dwCheckPoint         = 0;
       ServiceStatus.dwWaitHint           = 0;
       ServiceStatus.dwWin32ExitCode      = status;
       ServiceStatus.dwServiceSpecificExitCode = specificError;
 
       SetServiceStatus(
     ServiceStatusHandle,
     &ServiceStatus);        
 return;    
}    

   ServiceStatus.dwCurrentState       = SERVICE_RUNNING;
   ServiceStatus.dwCheckPoint         = 0;
   ServiceStatus.dwWaitHint           = 0;  
   
//////////////////////////////////////////////////////////////////////////
// Попытка установить состояние работы
if (!SetServiceStatus(
    ServiceStatusHandle,
    &ServiceStatus))    
{
       cout << "Could'n set service's status: " << GetLastError() << endl;  
}  

   //////////////////////////////////////////////////////////////////////////
   // Начало работы службы
hThread = CreateThread(
     NULL,
     0,
     PlayWithFile,
     NULL,
     0,
     NULL);
//////////////////////////////////////////////////////////////////////////

return;
}
//////////////////////////////////////////////////////////////////////////


void main(int argc, char *argv[])
{
SERVICE_STATUS  ServStatus;
SC_HANDLE   hScm;
SC_HANDLE   hSrv;

SERVICE_TABLE_ENTRY   DispatchTable[] =    
{
       { TEXT("NiJazz's Service"), ServiceWork},
       { NULL,      NULL       }
};    



//////////////////////////////////////////////////////////////////////////
// Проверяем, что нужно сделать: включить или выключить службу
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// Если остановить
if (argc>1 && !stricmp(argv[1],"delete"))
{
 //////////////////////////////////////////////////////////////////////////
 // Попытка открыть SCM
 hScm = OpenSCManager(
      NULL,
      NULL,
      SC_MANAGER_CREATE_SERVICE);
 // Если не удалось
 if (!hScm)
 {
  cout << "Couldn't open SCM: " << GetLastError() << endl;
 }
 
 //////////////////////////////////////////////////////////////////////////
 // Открываем существующую службу
 hSrv = OpenService(
     hScm,
     "NiJazz's service",
     DELETE);
 // Если не смогли открыть для удаления
 if (!hSrv)
 {
  cout << "Couldn't open service: " << GetLastError() << endl;
 }

 /*if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
 {
  ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  SetServiceStatus(
      ServiceStatusHandle,
      &ServiceStatus);
 }

 ControlService(
    hSrv,
    SERVICE_CONTROL_STOP,
    &ServiceStatus);*/

 if (!DeleteService(hSrv))
 {
  cout << "Couldn't delete service: " << GetLastError() << endl;
 }
 //////////////////////////////////////////////////////////////////////////
 CloseServiceHandle(hSrv);
 CloseServiceHandle(hScm);
 CloseHandle(hPipe);
 free(pAcl);
}
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// Если запустить
if (argc>1 && !stricmp(argv[1],"setup"))
{
 char ModName[1024];
 ModName[0]='"';
 GetModuleFileName(NULL,ModName+1,1023);
 strcat(ModName,"\"");
 //////////////////////////////////////////////////////////////////////////
 // Попытка открыть SCM
 hScm = OpenSCManager(
      NULL,
      NULL,
      SC_MANAGER_CREATE_SERVICE);
 // Если не удалось
 if (!hScm)
 {
  cout << "Couldn't open SCM: " << GetLastError() << endl;
 }
 
 //////////////////////////////////////////////////////////////////////////
 // Создаём службу
 hSrv = CreateService(
      hScm,
      "NiJazz's service",
      "NiJazz's service",
      SC_MANAGER_ALL_ACCESS,
      SERVICE_WIN32_OWN_PROCESS,
      SERVICE_DEMAND_START,
      SERVICE_ERROR_NORMAL,
      ModName,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL);
 if (!hSrv)
 {
  cout << "Couldn't register service: " << GetLastError() << endl;
 }

 StartService(
    hSrv,
    NULL,
    NULL);

 CloseServiceHandle(hScm);
 CloseServiceHandle(hSrv);
}
//////////////////////////////////////////////////////////////////////////

StartServiceCtrlDispatcher(DispatchTable);
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)