서비스 프로그램을 작성하다 보면..
간혹 데스크탑과 연동해야 하는 일이 발생한다.

입력없는 콘솔 프로그램 같은 경우는 그냥 서비스에서 바로 수행하면 되지만
입력을 받는 콘솔이나, GUI를 가진 프로그램을 띄워야할 경우는
프로세스 목록에만 나오고.. 깜깜 무소식이다.

일반 응용프로그램에서야 WTSRegisterSessionNotification 함수를 이용하여 아주 쉽게
로그온된 시점을 구할 수 있지만 불행하게도 서비스에서는 사용할 수 없다.


또한 서비스 시작시에 응용 프로그램을 수행시키면, 아직 로그온 되기 전이기때문에
저런 설정을 다 해놓는다 하여도 로그온된 화면에는 아무것도 보이지 않을 수 있다.

1. 꼭 서비스로 관리해야하는가?
2. 입력을 가지는 콘솔이나 GUI를 가졌는가?
3. 서비스 구동시에 시작해야 하는가?
4. 로그온 된 데스크탑에 보여주어야 하는가?

위 사항들을 잘 판단하고 그래도 꼭 필요하다면 다음과 같은 정보를 구해야한다.
1. 서비스로 개발하기
2. 데스크탑과 연동하는 옵션
3. 로그온된 시점 구하기

1. 서비스로 개발하기
위 사항은 이미 자료가 많이 나와있고, 대부분 알려진 자료이므로 그냥 좋은 자료를 찾는다 ^^;

2. 데스크탑과 연동하는 옵션
       첫번째로 가장 쉬운 방법은 서비스 관리자를 이용하는 방법이다.

사용자 삽입 이미지

     그림에서 보이는것 처럼 로그온 설정시에 서비스와 데스크탑 상호 작용 허용에 첵크를
     해줌으로써 아주 간단하게 해결할 수 있다.

     두번째는 서비스를 인스톨할 때, 즉 CreateService 함수를 이용하여 서비스를 설치할 때
     다섯번째 인자에 SERVICE_INTERACTIVE_PROCESS 를 함께 넣어주는 것이다.
     이것은 첫번째 방법을 프로그램적으로 해결하는 것이다.

3. 로그온된 시점 구하기
로그온된 시점을 구하는 방법도 그리 어렵지 않다. 하지만 제약사항이 많아서..
특히나 지금 처리하는 방법은 Windows XP 이상, Windows Server 2003 이상에서만
동작하는 방법이므로, 하위 버전 윈도우를 처리하는 경우에는 해당사항이 없다. -_-;;;
(예전에는 이벤트 로그를 뒤적거려서 처리했었다...)

서비스를 핸들하기 위하여 RegisterServiceCtrlHandler 함수 대신에 좀더 구체적인 정보를
전달해주는 RegisterServiceCtrlHandlerEx 를 이용하는 방법이다.

RegisterServiceCtrlHandlerEx API는 시스템의 세션정보 변화를 감지하는 이벤트인
WM_WTSSESSION_CHANGE 를 처리할 수 있도록 해준다.

SetServiceStatus 에서 SERVICE_STATUS 값의 dwControlsAccepted 값에 꼭
SERVICE_ACCEPT_SESSIONCHANGE 를 함께 넣어주도록 하자.

이렇게 RegisterServiceCtrlHandlerEx 에 전달된 콜백함수에는 다음과 같은 인자가 있다.
DWORD WINAPI HandlerEx(
  [in]                 DWORD dwControl,
  [in]                 DWORD dwEventType,
  [in]                 LPVOID lpEventData,
  [in]                 LPVOID lpContext
);

저기서 첫번째 인자에 SERVICE_CONTROL_SESSIONCHANGE 가 넘어오면 로그온 세션에
무언가 변화가 생긴것이다.

두번째 인자로 어떤 변화가 발생하였는지를 감지할 수 있다. MSDN의 설명을 참고해보면...
Value Meaning

WTS_CONSOLE_CONNECT
0x1

A session was connected to the console terminal.

WTS_CONSOLE_DISCONNECT
0x2

A session was disconnected from the console terminal.

WTS_REMOTE_CONNECT
0x3

A session was connected to the remote terminal.

WTS_REMOTE_DISCONNECT
0x4

A session was disconnected from the remote terminal.

WTS_SESSION_LOGON
0x5

A user has logged on to the session.

WTS_SESSION_LOGOFF
0x6

A user has logged off the session.

WTS_SESSION_LOCK
0x7

A session has been locked.

WTS_SESSION_UNLOCK
0x8

A session has been unlocked.

WTS_SESSION_REMOTE_CONTROL
0x9

A session has changed its remote controlled status. To determine the status, call GetSystemMetrics and check the SM_REMOTECONTROL metric.


그러므로 위시점에서 WTS_SESSION_LOGON 일 경우에 프로그램을 기동시키면 정확하게
로그온된 시점에 프로그램이 구동하게 된다.

+ Recent posts