1. 학교 컴퓨터실과 군부대 PC의 서비스 마비 잔혹사: "Print Spooler 충돌과 Windows Update 무한 루프"
Windows 운영체제의 백그라운드 서비스(Windows Services)는 시스템의 생명선이지만, 동시에 장애 발생 시 가장 진단하기 어려운 영역입니다:
- 프린터 스풀러(Print Spooler)의 잦은 데드락: 손상된 인쇄 큐나 네트워크 프린터 타임아웃으로 인해 스풀러 서비스가 멈추면 컴퓨터실 전체 40대 PC의 인쇄가 마비됩니다.
- Windows Update(wuauserv)의 CPU/디스크 점유: 수업 시간 도중 업데이트 서비스가 백그라운드에서 실행되면서 구형 교육용 PC의 스토리지를 100% 점유하여 수업이 중단됩니다.
- 보안 소프트웨어 및 에이전트의 좀비화: 바이러스 백신이나 유해 사이트 차단 에이전트가 정상 종료되지 못하고 고아 프로세스로 남아 시스템 메모리를 잠식합니다.
2. 윈도우 기본 서비스 관리자(services.msc)의 한계: "느린 검색, 필터링 부재, 서비스 정보 복사 불가"
Windows의 기본 서비스 관리 콘솔(services.msc)은 20년 전의 MMC(Microsoft Management Console) 아키텍처에 갇혀 있습니다:
- 실시간 검색(Search) 기능 부재: 서비스를 찾으려면 첫 글자를 타이핑하거나 스크롤바를 일일이 내려야 하며, 서비스 설명(Description)이나 실행 경로(PathName)를 기반으로 한 검색은 불가능합니다.
- 상태별 필터링 불가: "현재 실행 중인 서비스만 보기" 혹은 "자동 시작인데 중지된 비정상 서비스만 보기"와 같은 기초적인 필터조차 지원하지 않습니다.
- 상세 정보 원클릭 복사 불가: 서비스 이름, 실제 바이너리 경로, PID를 IT 지원팀이나 상급 기관에 전송하려면 속성 창을 열어 마우스로 드래그해야 하는 극심한 비효율이 발생합니다.
3. WMI Win32_Service WQL 비동기 쿼리 엔진: 수백 개 시스템 서비스의 0초 인벤토리 수집
System.ServiceProcess.ServiceController 클래스는 간단하지만, 각 서비스의 상세 설명(Description), 실행 파일 경로(PathName), 프로세스 ID(PID)를 가져오지 못합니다.
ZeliService는 WMI(Windows Management Instrumentation)의 Win32_Service 클래스를 WQL(WMI Query Language)로 비동기 질의하여, 단 한 번의 호출로 시스템 내 300여 개 서비스의 모든 메타데이터를 0초 만에 완벽하게 수집합니다:
private async Task LoadServicesAsync()
{
SetStatus(string.Format("🔄 {0}", Loc.Get("Svc_Scanning")), "");
var services = await Task.Run(() =>
{
var list = new List<ServiceItem>();
try
{
using var searcher = new ManagementObjectSearcher(
"SELECT Name, DisplayName, State, StartMode, Description, ProcessId, PathName FROM Win32_Service");
foreach (ManagementObject obj in searcher.Get())
{
var state = obj["State"]?.ToString() ?? "";
list.Add(new ServiceItem
{
ServiceName = obj["Name"]?.ToString() ?? "",
DisplayName = obj["DisplayName"]?.ToString() ?? "",
Status = state,
StatusIcon = state switch
{
"Running" => "🟢",
"Stopped" => "🔴",
"Paused" => "🟡",
"Start Pending" => "🟠",
"Stop Pending" => "🟠",
_ => "⚪"
},
StartType = obj["StartMode"]?.ToString() switch
{
"Auto" => Loc.Get("Svc_StartTypeAuto"),
"Manual" => Loc.Get("Svc_StartTypeManual"),
"Disabled" => Loc.Get("Svc_StartTypeDisabled"),
var x => x ?? ""
},
Description = obj["Description"]?.ToString() ?? "",
Pid = Convert.ToInt32(obj["ProcessId"] ?? 0),
PathName = obj["PathName"]?.ToString() ?? ""
});
}
}
catch (Exception ex)
{
Debug.WriteLine($"[ZeliService] WMI error: {ex.Message}");
}
return list.OrderBy(s => s.DisplayName).ToList();
});
_allServices = services;
ApplyFilter();
}
4. 상태별 이모지 시각화와 다중 필드(이름·표시명·설명) 실시간 스트리밍 필터
사용자는 텍스트로 된 영문 상태 대신, 한눈에 직관적으로 파악할 수 있는 시각적 힌트를 원합니다. ZeliService는 4대 상태에 직관적인 이모지(🟢/🔴/🟡/🟠)를 부여하고, 사용자가 검색창에 타이핑하는 즉시 대소문자 구분 없이 서비스명, 표시 이름, 설명문까지 전방위 대조합니다:
private void ApplyFilter()
{
var filtered = _allServices.AsEnumerable();
// 1. 상태 콤보박스 필터링 (전체 / Running / Stopped / Auto)
int filterIdx = CboFilter.SelectedIndex;
filtered = filterIdx switch
{
1 => filtered.Where(s => s.Status == "Running"),
2 => filtered.Where(s => s.Status == "Stopped"),
3 => filtered.Where(s => s.StartType == Loc.Get("Svc_StartTypeAuto")),
_ => filtered
};
// 2. 텍스트 다중 필드 실시간 검색
string search = TxtSearch.Text?.Trim() ?? "";
if (!string.IsNullOrEmpty(search))
{
filtered = filtered.Where(s =>
s.ServiceName.Contains(search, StringComparison.OrdinalIgnoreCase) ||
s.DisplayName.Contains(search, StringComparison.OrdinalIgnoreCase) ||
(s.Description?.Contains(search, StringComparison.OrdinalIgnoreCase) ?? false));
}
var result = filtered.ToList();
_displayServices.Clear();
foreach (var s in result) _displayServices.Add(s);
TxtCount.Text = $"({result.Count}/{_allServices.Count})";
}
5. sc.exe 래핑과 Verb=runas를 통한 안전한 UAC 승격 및 Win32Exception 샌드박싱
윈도우 시스템 서비스를 제어하려면 반드시 관리자 권한이 필요합니다. 그러나 앱 전체를 처음부터 '관리자 권한으로 실행'하도록 강제하면, 권한이 없는 일반 학생 계정에서는 프로그램 실행 자체가 차단되는 심각한 문제가 발생합니다.
ZeliService는 최소 권한의 원칙(Principle of Least Privilege)을 적용합니다. 일반 읽기 및 검색은 일반 사용자 권한으로 0초 만에 구동하고, 사용자가 특정 서비스의 시작/중지를 요청할 때만 Windows의 신뢰받는 네이티브 도구인 sc.exe를 Verb = "runas"로 격리 실행합니다:
private async Task RunScCommand(string action, string serviceName)
{
try
{
var psi = new ProcessStartInfo
{
FileName = "sc.exe",
Arguments = $"{action} \"{serviceName}\"",
UseShellExecute = true,
Verb = "runas" // 필요한 순간에만 UAC 권한 승격 창 요청
};
var proc = Process.Start(psi);
if (proc != null) await proc.WaitForExitAsync();
await Task.Delay(1000);
await LoadServicesAsync(); // 서비스 상태 자동 리로드
SetStatus(string.Format("✅ {0}", string.Format(Loc.Get("Svc_ActionComplete"), serviceName, action)), "");
}
catch (System.ComponentModel.Win32Exception)
{
// 사용자가 UAC 승인 팝업에서 '아니오'를 누르거나 권한 거부 시 안전 격리
SetStatus(string.Format("❌ {0}", Loc.Get("Svc_NeedAdmin")), "");
}
catch (Exception ex)
{
SetStatus(string.Format("❌ {0}: {1}", Loc.Get("Common_Error"), ex.Message), "");
}
}
6. 가역적 서비스 재시작(Restart) 파이프라인: 원자적 정지-지연-기동-재스캔 시퀀스
먹통이 된 서비스를 정상화할 때 가장 안전한 방법은 '완전한 정지(Stop) ➔ 프로세스 자원 반환 대기 ➔ 깨끗한 재시작(Start)'입니다. 윈도우 기본 도구는 정지 중 타임아웃이 나면 서비스가 '중지 중(Stop Pending)' 상태로 굳어버리기 십상입니다.
ZeliService의 재시작 파이프라인은 2,000ms의 완충 시간을 두어 소켓과 I/O 핸들이 온전히 닫히도록 유도한 후 기동하며, 곧바로 WMI 재스캔을 수행하여 실제 가동 여부를 시각적으로 확정합니다:
private async void BtnRestart_Click(object sender, RoutedEventArgs e)
{
var svc = GetSelectedService();
if (svc == null) { SetStatus(string.Format("⚠️ {0}", Loc.Get("Svc_SelectService")), ""); return; }
SetStatus(string.Format("🔁 {0}", string.Format(Loc.Get("Svc_Restarting"), svc.DisplayName)), "");
// Step 1: 안전 정지 명령
await RunScCommand("stop", svc.ServiceName);
// Step 2: 자원 반환 및 프로세스 정리 대기 (2초 완충)
await Task.Delay(2000);
// Step 3: 깨끗한 재시동
await RunScCommand("start", svc.ServiceName);
// Step 4: 완료 후 LoadServicesAsync가 자동 호출되어 최신 상태 반영
}
7. 윈도우 서비스 관리 도구(services.msc vs PowerShell Get-Service vs Process Hacker vs ZeliService) 비교 분석
학교 전산실 및 국방 폐쇄망 환경의 관점에서 기존 솔루션들과 비교 분석한 결과는 다음과 같습니다:
| 비교 항목 | Windows services.msc | PowerShell (Get-Service) | Process Hacker (상용/오픈소스) | ZeliService (온디바이스) |
|---|---|---|---|---|
| 설치 및 구동 방식 | OS 내장 MMC | CLI 터미널 명령어 | 설치 필요 (드라이버 적재) | Zero-Install 무설치 네이티브 C# |
| 초기 실행 권한 요구 | 일반 권한 (수정 시 차단) | 터미널 권한 종속 | 관리자 권한 필수 (KProcessHacker) | 일반 권한 0초 로드 + 필요시만 UAC |
| 실시간 스트리밍 검색 | 미지원 (첫 글자 점프만 가능) | Where-Object 스크립트 작성 | 텍스트 필터 지원 | 이름·표시명·설명 다중 실시간 검색 |
| 상태 시각화 | 텍스트 (시작됨/중지됨) | 텍스트 | 색상 하이라이트 | 4대 상태 직관적 이모지(🟢/🔴/🟡/🟠) |
| 서비스 정보 원클릭 복사 | 미지원 (수동 드래그) | 파이프라인 포맷팅 필요 | 속성 창 복사 | 이름·경로·PID·설명 클립보드 원클릭 |
| 공공기관 라이선스 단속 | 무관 | 무관 | 보안 정책 위반 우려(드라이버 차단) | 완전 무상 보급 / 100% 라이선스 프리 |
8. 결론: "상용 라이선스 단속과 블루스크린 공포 없는 공교육·국방 전산 인프라 서비스 거버넌스"
멈춰버린 서비스 하나가 수십 명의 수업을 중단시키고 업무망을 마비시킬 수 있습니다. 하지만 문제를 해결하기 위해 시스템 커널 드라이버를 건드리는 무거운 전문 도구를 설치하는 것은 시스템 안정성에 더 큰 위험을 초래합니다.
ZeliDesk의 ZeliService는 마이크로소프트의 표준 WMI 인프라와 신뢰받는 sc.exe만을 완벽하게 조합하여, 관리자 권한 없는 일반 계정에서도 안전하게 전체 서비스를 진단하고 꼭 필요한 순간에만 최소한의 UAC 승격으로 문제를 해결합니다. 이제 전국의 교육 현장과 공공 전산망은 가장 안전하고 스마트한 방식으로 백그라운드 서비스 라이프사이클을 통제할 수 있습니다.