본문 바로가기
Programming/Tips(C++,C#)

0122 - 서비스프로그래밍 (2). 서비스프로그램등록/제거

by 곰네Zip 2009. 1. 22.

1. Install Service Program
void CServiceManagerDlg::OnButtonInstall()
{
 // TODO: Add your control notification handler code here
 SC_HANDLE hServiceManager    = NULL;
 SC_HANDLE hService     = NULL;
 TCHAR  szPath[MAX_PATH+_MAX_FNAME] = {0}; 

 //step
 //1. 운영체제의 서비스매니저에 연결
 hServiceManager = ::OpenSCManager(NULL, NULL,SC_MANAGER_CREATE_SERVICE);

 if(hServiceManager == NULL){
  AfxMessageBox(_T("Error: Failed to open Service manager"));
  return;
 }

 //2. 설치할 서비스 파일 확인

 //3. 새로운 서비스를 생성하여 등록함
 hService = ::CreateService(
     hServiceManager,
     _T("ServiceSample"),
     _T("서비스프로그래밍 예제 서비스입니다."),
     SERVICE_ALL_ACCESS,
     SERVICE_WIN32_OWN_PROCESS,
//DISABLED,SYSTEM_START(제일빠른타임),BOOT_START,AUTO_START
     SERVICE_DEMAND_START,
     SERVICE_ERROR_NORMAL,
     _T(".\\ServiceSample.exe"),
     NULL,//Group
     NULL, //식별자태그
     NULL, //dependancy
     NULL, //local account
     NULL); //Password

 if( hService == NULL){
  DWORD dwError = ::GetLastError();

  if(dwError == ERROR_SERVICE_EXIST){
   AfxMessageBox(_T("ServiceSample 서비스가 이미 존재합니다."));
  }
  else if(dwError == ERROR_DUP_NAME){
   AfxMessageBox(_T("같은 이름의 서비스가 이미 존재합니다."));
  }
  else{
   CString strTmp = _T("");
   strTmp.Format(_T("서비스를 생성할 수 없습니다. [%d]"),dwError);
   AfxMessageBox(strTmp);
  }
 }
 else{
  //4.서비스등록
  SERVICE_DESCRIPTION desc;
  desc.lpDescription = _T("이 서비스는 서비스 프로그래밍을 학습하기 위한 서비스");
  ::ChangeServiceConfig2(hService,
       SERVICE_CONFIG_DESCRIPTION,
       &desc);
 }
 //5.완료 - 서비스닫고 서비스매니저를 닫아야한다.
 ::CloseServiceHandle(hService);
 ::CloseServiceHandle(hServiceManager);

}

2. Service Uninstall
void CServiceManagerDlg::OnButtonUninstall()
{
 // TODO: Add your control notification handler code here
 SERVICE_STATUS ss = {0};
 SC_HANDLE hServiceManager = NULL;
 SC_HANDLE hService   = NULL;

 //1. connect service manager
 hServiceManager = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

 if( hServiceManager == NULL){
  AfxMessageBox(_T("Error : Failed to open service manager."));
  goto ENDERROR;
 }

 //2. open service, for stop one to remove
 hService = ::OpenService(hServiceManager, _T("ServiceSample"),SERVICE_ALL_ACCESS);
 if( hServiceManager == NULL){
  AfxMessageBox(_T("Error : Failed to open service.")); 
  goto ENDERROR;
 }

 //3. stop service
 ::QueryServiceStatus(hService, &ss);
 if( ss.dwCurrentState != SERVICE_STOPPED){
  ::ControlService(hService, SERVICE_CONTROL_STOP, &ss);
  ::Sleep(1000); //wait for stop services
  //서비스 정지중에 progress바 올라가는건 낚시다. 허전하지말라고
 }

 //4. remove service
 if(::DeleteService(hService)){
  AfxMessageBox(_T("서비스가 제거됨"));
 }else{
  AfxMessageBox(_T("서비스를 제거할수 없음"));
 }

ENDERROR:
 if( hService != NULL)   ::CloseServiceHandle(hService);
 if( hServiceManager != NULL) ::CloseServiceHandle(hServiceManager);
}

* +@
만약 서비스가 종료되는 코드에서..
::CloseHandle(g_hEventExit);
 LogPrint(_T("Sample 서비스가 정상적으로 종료됨"),EVENTLOG_INFORMATION_TYPE);

 STARTUPINFO si = {0};
 PROCESS_INFORMATION pi = {0};

 ::CreateProcess/*AsUser*/(NULL,
     _T("notepad.exe"),
     NULL,
     NULL,
     TRUE,
     0,
     NULL,
     NULL,
     &si,
     &pi);

 ::CloseHandle(pi.hProcess);
 ::CloseHandle(pi.hThread);

이런짓거리로 생긴 노트패드는 슈퍼메모장이다.. ㄷㄷㄷㄷ

 SetSampleServiceStatus(SERVICE_STOPPED,NO_ERROR,0);

*중요한것은 어떻게 서비스를 등록/실행시킬 것인가. 그리고 실행할 떄 권한을 어떻게 먹을것인가. ㅋㅋㅋㅋㅋㅋㅋ 이것이 제일 중요하다. 이거만 잘하면 윈도우가 뚫린다~~~

반응형

댓글