연초에 .NET 4.0으로 작성한 Windows 서비스가 하나 있다. 이걸 개발 팀 – 운영 팀 사이에서 쓰고 있는데, 지난 주 목요일에 이게 동작하지 않는다고 연락이 왔다. 그에 해당하는 시점이 "시스템 업데이트를 위해 머신 재 시작 후"라서 그게 문젤까 의심했는데, 문제가 생기도록 변경된 부분이 딱 하나였다.
운영 팀에서 "서비스와 데스크톱 상호 작용 허용" (allow service to interact with desktop) 설정을 켰음 – 이유는 모르겠지만, 대부분의 개발팀이 이 설정을 요구한다고; 계정은 로컬 시스템 계정 (local administrator) 였고; 여하튼 이 설정이 켜져서 문제가 된 부분은 대략 이렇다:
- 개발 편의성을 도모하고자, 1개의 바이너리가 서비스 혹은 콘솔 창 모드로 동작함
- 이 두 가지를 Environment.UserInteractive 값을 가지고 구분했다
- "서비스와 데스크톱 상호 작용 허용"이 체크되어 있으면, Environment.UserInteractive가 true로 설정된다
- …그리고 내가 작성한 서비스는 콘솔 창을 띄웠다 (…)
Orz.
부연하자면, 서비스는 세션 0에서 실행되기 때문에 ((Session 0 isolation 참고)) 사용자가 터미널 접속한 경우, "이런 이런 서비스에서 창을 띄우려고 합니다"란 메시지를 받게 된다. 그리고 그런 유저가 없으니 – 서비스는 보통 sc \\host-name start blah-blah-service 명령이나 관제 툴로 띄운다 – 서비스는 더 진행하지 못하고 사망. 일정 시간 안에 서비스를 시작하지 못하면 서비스 매니저는 그 서비스를 죽여버린다(…).
결과:
- 일단 그 날 저 체크 박스 꺼버리는 걸로 문제 해결.
- Environment.UserInteractive 말고도 SessionID를 확인하도록 코드 추가. (세션 0이면 서비스로 뜨게)
.NET을 잘 모르고 써서 생긴 문제긴 한데, 내가 운영 매뉴얼?을 좀 만들었으면 괜찮았을지도 모르겠다. 으으.
일단 응용 프로그램으로 만들고 어디서 서비스 만드는 코드 들고 와서 붙이면 저 플래그 켜줘야 제대로 돌아간다거나 (레지스트리 접근 범위라던지가 틀려졌던거 같은데) GUI가 붙어있기 때문에 저 플래그를 켜줘야 한다거나 하는 시절이 있었는데 지금도 그런지는 모르겠군.
역시 과거의 유산(?)인건가요; 으음;;;