| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
Tags
- BST
- template
- 기초
- 바이낸스
- #선물 #비트코인#알트코인#매매#코인#마진
- 숫자
- trading view
- 자료구조
- 선물
- 순회
- 오버로딩
- 문자열
- linked list
- C++
- Windows
- Python
- 트리
- mutable
- 알고리즘
- 연결 리스트
- Data Structure
- Basic
- 이진 탐색 트리
- Tree
- 전위
- 후위
- SCM
- 템플릿 함수화
- 비트코인
- array
Archives
- Today
- Total
Project Hub
1. 서비스 제어 관리자 (SCM : Service Control Manager) 구현 본문
728x90
반응형
참고 사항
더보기
Service 란?
Windows 에서 실행되는 프로그램 종류 중 하나
백그라운드에서 실행되는 프로그램
사용자에게 보이지 않지만 시스템 유지, 데이터 제공, 하드웨어 관리 등의 기능 수행
UI 없음
서버 응용 프로그램이므로 NT, 서버급 windows 에서만 설치/실행 됨.
레지스트리에 등록 (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Service)
services.msc (서비스 애플릿)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Service 해당 경로에 부팅 시 실행해야 하는 서비스 목록이 기록됨
이 레지스트리에 있는 정보를 서비스 데이터 베이스 라고 부름.
SCM을 GUI로 확인할 수 있음.
Service Control Manager(이하 SCM) 이란?
윈도우 서비스 프로세스와 시작과 정지 및 상호작용 하는 윈도우 NT 하의 특별한 시스템 프로세스.
서비스 DB를 관리하는 시스템 프로그램.
SCM 구현
- service control 을 위한 기능을 클래스화하여 사용에 용이하도록 함.
#pragma once
#include <stdio.h>
#include <Windows.h>
#include <winsvc.h>
class CControlService
{
public:
CControlService();
virtual ~CControlService();
public:
DWORD CreateService(IN LPCTSTR lpServiceName,
IN LPCTSTR lpDisplayName,
IN DWORD dwServiceType,
IN DWORD dwStartType,
IN LPCTSTR lpBinaryPathName,
IN LPCTSTR lpLoadOrderGroup,
OUT LPDWORD lpdwTagId,
IN LPCTSTR lpDependencies,
IN LPCTSTR lpServiceStartName,
IN LPCTSTR lpPassword);
DWORD ChangeServiceConfig(LPCTSTR lpServiceName, DWORD dwStartType, LPCTSTR lpszDescription);
DWORD StartService(LPCTSTR lpServiceName);
DWORD StopService(LPCTSTR lpServiceName);
DWORD PauseService(LPCTSTR lpServiceName);
DWORD ContinueSerivce(LPCTSTR lpServiceName);
DWORD ShutdownService(LPCTSTR lpServiceName);
DWORD DeleteService(LPCTSTR lpServiceName);
BOOL IsServiceInstalled(LPCTSTR lpServiceName);
BOOL IsServiceRunning(LPCTSTR lpServiceName);
};
- 함수 구현 내용
더보기
#include "ControlService.h"
CControlService::CControlService()
{
}
CControlService::~CControlService()
{
}
DWORD CControlService::CreateService(IN LPCTSTR lpServiceName,
IN LPCTSTR lpDisplayName,
IN DWORD dwServiceType,
IN DWORD dwStartType,
IN LPCTSTR lpBinaryPathName,
IN LPCTSTR lpLoadOrderGroup,
OUT LPDWORD lpdwTagId,
IN LPCTSTR lpDependencies,
IN LPCTSTR lpServiceStartName,
IN LPCTSTR lpPassword)
{
DWORD dwRet = ERROR_SUCCESS;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); //Required to call the CreateService function to create a service object and add it to the database.
if (schSCManager)
{
schService = ::CreateService(schSCManager,
lpServiceName, // "TEST_Service"
lpDisplayName, // "TEST_Service"
SERVICE_ALL_ACCESS,
dwServiceType, // SERVICE_WIN32_OWN_PROCESS
dwStartType, // SERVICE_AUTO_START
SERVICE_ERROR_NORMAL,
lpBinaryPathName, // "Service program path" -> "" 이 없을 경우 시스템에 따라서 서비스 시작시 193 에러가 반환됨.
lpLoadOrderGroup, // NULL
lpdwTagId, // NULL
lpDependencies, // "\0"
lpServiceStartName, // NULL
lpPassword); // NULL
if (schService)
::CloseServiceHandle(schService);
// 이미 서비스가 있는 경우, ERROR_SERVICE_EXISTS 리턴
else if (ERROR_SERVICE_EXISTS != GetLastError())
dwRet = GetLastError();
::CloseServiceHandle(schSCManager);
}
else
{
dwRet = GetLastError();
}
return dwRet;
}
DWORD CControlService::ChangeServiceConfig(LPCTSTR lpServiceName, DWORD dwStartType, LPCTSTR lpszDescription)
{
DWORD dwRet = ERROR_SUCCESS;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager)
{
schService = ::OpenService(schSCManager, lpServiceName, SERVICE_CHANGE_CONFIG);
if (schService)
{
if (!::ChangeServiceConfig(schService, // handle of service
SERVICE_NO_CHANGE, // service type: no change
dwStartType, // change service start type
SERVICE_NO_CHANGE, // error control: no change
NULL, // binary path: no change
NULL, // load order group: no change
NULL, // tag ID: no change
NULL, // dependencies: no change
NULL, // account name: no change
NULL, // password: no change
lpszDescription)) // display name
{
dwRet = GetLastError();
}
//:) NT4.0에서는 ChangeServiceConfig2()가 없다.
#if _MSC_VER >= 1500
SERVICE_DESCRIPTION sd = {0};
sd.lpDescription = const_cast<LPWSTR>(lpszDescription);
if( !::ChangeServiceConfig2(
schService, // handle to service
SERVICE_CONFIG_DESCRIPTION, // change: description
&sd) ) // new description
{
dwRet = GetLastError();
}
#endif
::CloseServiceHandle(schService);
}
else
{
dwRet = GetLastError();
}
::CloseServiceHandle(schSCManager);
}
else
{
dwRet = GetLastError();
}
return dwRet;
}
DWORD CControlService::StartService(LPCTSTR lpServiceName)
{
DWORD dwRet = ERROR_SUCCESS;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); // local computer, SERVICES_ACTIVE_DATABASE
if (schSCManager)
{
schService = ::OpenService(schSCManager, lpServiceName, SERVICE_ALL_ACCESS);
if (schService)
{
if (!::StartService(schService, 0, NULL))
{
if (ERROR_SERVICE_ALREADY_RUNNING != GetLastError())
dwRet = GetLastError();
}
::CloseServiceHandle(schService);
}
else
{
dwRet = GetLastError();
}
::CloseServiceHandle(schSCManager);
}
else
{
dwRet = GetLastError();
}
return dwRet;
}
DWORD CControlService::StopService(LPCTSTR lpServiceName)
{
DWORD dwRet = ERROR_SUCCESS;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
SERVICE_STATUS ss;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (schSCManager)
{
schService = ::OpenService(schSCManager, lpServiceName, SERVICE_QUERY_STATUS | SERVICE_STOP); // SERVICE_QUERY_STATUS?
if (schService)
{
::ControlService(schService, SERVICE_CONTROL_STOP, &ss);
::CloseServiceHandle(schService);
}
else
{
dwRet = GetLastError();
}
::CloseServiceHandle(schSCManager);
}
else
{
dwRet = GetLastError();
}
return dwRet;
}
DWORD CControlService::PauseService(LPCTSTR lpServiceName)
{
DWORD dwRet = ERROR_SUCCESS;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (schSCManager)
{
schService = ::OpenService(schSCManager, lpServiceName, SERVICE_ALL_ACCESS);
if (schService)
{
if (NULL == ::ControlService(schService, SERVICE_CONTROL_PAUSE, NULL))
{
dwRet = GetLastError();
}
::CloseServiceHandle(schService);
}
else
{
dwRet = GetLastError();
}
::CloseServiceHandle(schSCManager);
}
else
{
dwRet = GetLastError();
}
return dwRet;
}
DWORD CControlService::ContinueSerivce(LPCTSTR lpServiceName)
{
DWORD dwRet = ERROR_SUCCESS;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (schSCManager)
{
schService = ::OpenService(schSCManager, lpServiceName, SERVICE_ALL_ACCESS);
if (schService)
{
if (NULL == ::ControlService(schService, SERVICE_CONTROL_CONTINUE, NULL))
{
dwRet = GetLastError();
}
::CloseServiceHandle(schService);
}
else
{
dwRet = GetLastError();
}
::CloseServiceHandle(schSCManager);
}
else
{
dwRet = GetLastError();
}
return dwRet;
}
DWORD CControlService::ShutdownService(LPCTSTR lpServiceName)
{
DWORD dwRet = ERROR_SUCCESS;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (schSCManager)
{
schService = ::OpenService(schSCManager, lpServiceName, SERVICE_ALL_ACCESS);
if (schService)
{
if (NULL == ::ControlService(schService, SERVICE_CONTROL_SHUTDOWN, NULL))
{
dwRet = GetLastError();
}
::CloseServiceHandle(schService);
}
else
{
dwRet = GetLastError();
}
::CloseServiceHandle(schSCManager);
}
else
{
dwRet = GetLastError();
}
return dwRet;
}
DWORD CControlService::DeleteService(LPCTSTR lpServiceName)
{
DWORD dwRet = ERROR_SUCCESS;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); // local computer, SERVICES_ACTIVE_DATABASE
if (schSCManager)
{
schService = ::OpenService(schSCManager, lpServiceName, DELETE);
if (schService)
{
if (!::DeleteService(schService))
dwRet = GetLastError();
::CloseServiceHandle(schService);
}
else
{
dwRet = GetLastError();
}
::CloseServiceHandle(schSCManager);
}
else
{
dwRet = GetLastError();
}
return dwRet;
}
BOOL CControlService::IsServiceInstalled(LPCTSTR lpServiceName)
{
BOOL bRet = FALSE;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (schSCManager)
{
schService = ::OpenService(schSCManager, lpServiceName, SERVICE_QUERY_CONFIG);
if (schService)
{
bRet = TRUE;
::CloseServiceHandle(schService);
}
::CloseServiceHandle(schSCManager);
}
return bRet;
}
BOOL CControlService::IsServiceRunning(LPCTSTR lpServiceName)
{
BOOL bRet = FALSE;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
SERVICE_STATUS ss;
schSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (schSCManager)
{
schService = ::OpenService(schSCManager, lpServiceName, SERVICE_QUERY_CONFIG|SERVICE_QUERY_STATUS);
if (schService)
{
if (::QueryServiceStatus(schService, &ss))
{
if (SERVICE_RUNNING == ss.dwCurrentState)
bRet = TRUE;
}
::CloseServiceHandle(schService);
}
::CloseServiceHandle(schSCManager);
}
return bRet;
}
향후 진행 & 추가 확인해야 할 내용
- service 프로그램 구현하여 SCM을 활용해 제어하는 과정 확인.
- SCM도 singleton 필요?
- 서비스 속성 제어에 대한 부분도 추가 확인 필요.
728x90
반응형
'Windows > Windows Service' 카테고리의 다른 글
| 2. ServiceApp 구현 및 서비스 실행 (1) | 2022.08.06 |
|---|
Comments