Windows 네이티브 앱 개발은 엉망이다

Windows native app development is a mess

요약

작가가 Windows 유틸리티 앱 개발을 시도하면서 Win32 API부터 WPF, UWP에 이르는 Windows 개발 생태계의 혼란스러운 역사와 현재의 복잡성을 분석합니다. 개발자들이 네이티브 Windows 앱 대신 Electron을 선택하는 이유를 설명합니다.

핵심 포인트

  • Win32 API, .NET, WPF, WinRT, UWP 등 여러 추상화 계층이 중복되어 개발 난이도 증가
  • 각 새로운 프레임워크 도입 시 이전 API와의 호환성 문제와 새로운 기능 제한 발생
  • 일관된 개발 경험의 부재로 크로스 플랫폼 도구(Electron 등)로의 이동 심화

왜 중요한가

Windows 네이티브 개발자가 직면한 생태계의 복잡성을 이해하고 기술 선택 시 고려사항을 파악하는 데 도움이 됩니다.

📄 전문 번역

Windows 네이티브 앱 개발, 정말 복잡할까?

저는 처음부터 Windows 개발자였습니다. 열 살 때 『Beginning Visual C++ 6』라는 책을 읽으며 Visual C++ 체험판을 부모님 컴퓨터에 설치했던 기억이 아직도 생생합니다. .NET 1.0이 나왔을 때는 가족 휴가 중에 C# 책을 들고 있었고, 당시 MFC로 만든 네오펫 핵킹 프로그램들을 Windows Forms로 다시 짜려고 열심이었죠. 대학 졸업 후 첫 직장도 .NET 회사였는데, 다행히 프론트엔드 업무를 맡았습니다.

Windows 개발 생태계를 멀찍이서 지켜봤지만, 실제로 네이티브 Windows 앱을 만들어본 적은 없었어요. (Chromium도 기술적으로는 네이티브 앱이지만, 자기만의 운영체제나 다름없습니다.) 취미 프로젝트는 항상 웹이 더 편했거든요. 그런데 어릴 적 추억이 자꾸만 떠올랐습니다. 은퇴 프로젝트로 재미있는 Windows 유틸리티를 만들어보면 좋을 것 같다고 생각했죠.

결과는 어땠냐고요? 이 분야가 정말 엉망이라는 걸 깨달았습니다. 요즘 아무도 Windows 네이티브 앱을 안 쓰고 Electron으로 넘어가는 이유가 이제야 이해됩니다.

내가 만든 프로그램

Display Blackout이라는 유틸리티입니다. 세 개의 모니터로 게임을 할 때, 좌우 모니터를 까맣게 만들고 싶었거든요. 모니터를 끄면 Windows가 몇 초간 버벅거리며 윈도우 배치가 엉망이 됩니다. 하지만 OLED 모니터라면 검은 오버레이만 띄워도 모든 픽셀이 꺼지니 마찬가지 효과를 낼 수 있죠.

물론 이 아이디어가 제 독창적인 건 아닙니다. 원래 AutoHotkey 스크립트를 쓰고 있었는데, 나중에 확인해보니 벌써 정식 Windows 앱으로 진화했더라고요. Microsoft Store에도 비슷한 프로그램들이 여럿 있습니다. 그래도 UI를 조금 더 깔끔하고 현대적으로 만들 수 있을 것 같았고, 뭣보다 배우는 게 목적이었으니까요.

이 프로그램이 필요한 기능들을 정리하면 다음과 같습니다:

  • 연결된 디스플레이 목록과 해상도 정보 조회
  • 테두리와 제목 표시줄 없는 검은 창을 맨 앞에 표시
  • 전역 키보드 단축키 감지
  • 시작 시 자동 실행 옵션
  • 설정값 저장
  • 시스템 트레이 아이콘과 메뉴

이 정도 기능을 염두에 두고 계속 읽어보세요.

(제가 만든 UI를 보면 진짜 아름답다고 동의하실 겁니다. 이 분야의 다른 모든 소프트웨어보다 낫습니다.)

Windows 프로그래밍의 역사

처음에는 C로 만든 Win32 API가 있었습니다. 불행히도 오늘날에도 여전히 중요합니다.

시간이 지나면서 여러 추상화 계층이 쌓여갔습니다. .NET 이전의 주요 시도는 MFC C++ 라이브러리였는데, 당시 최신 언어 기능인 클래스와 템플릿으로 원시적인 C 함수 위에 객체 지향성을 얹었죠.

.NET이 나오면서 진짜 변화가 일어났습니다. 특히 중요한 건 C#이라는 새로운 언어가 도입되었다는 겁니다. Java처럼 가상 머신 위에서 JIT 컴파일되는 바이트코드로 동작했어요. 덕분에 자동 메모리 관리와 메모리 안전성이 Windows 개발에 들어왔고, Microsoft도 더 현대적인 기초를 갖추게 됐습니다. .NET 라이브러리는 Windows와 상호작용하는 완전히 새로운 API 세트를 제공했습니다. UI 쪽으로는 .NET 1.0(2002)에 Windows Forms가 등장했는데, MFC처럼 Win32 윈도우와 컨트롤 API를 래핑한 것이었습니다.

.NET 3.0(2006)에 들어서면서 WPF가 나왔습니다. 이제 모든 컨트롤을 C# 객체로 만드는 대신, XAML이라는 별도의 마크업 언어를 썼습니다. HTML + JavaScript 같은 관계였죠. 특히 처음으로 Win32 API 컨트롤을 감싸는 대신 GPU에서 컨트롤을 직접 그렸습니다. 당시엔 정말 신선한 출발 같았고, 앞으로의 Windows 앱 미래를 위한 견고한 토대라고 생각했어요.

Windows 8(2012)과 함께 WinRT가 나오면서 또 다른 큰 변화가 일어났습니다. .NET처럼 Windows 앱을 만드는 데 필요한 모든 기능을 위한 새로운 API를 만들려는 시도였습니다. 개발자가 WinRT 범위 안에서만 작업하면, Android나 iOS처럼 샌드박스된 현대식 앱이 되어 Windows 데스크톱, 태블릿, 휴대폰에 배포할 수 있었죠. UI는 여전히 XAML 기반이었지만, 다양한 기기를 지원하기 위해 모든 게 WPF와 조금씩 달랐습니다.

Windows 10(2015)에서는 UWP로 다시 한번 리셋했습니다. 샌드박싱 제한을 좀 풀어서 데스크톱, 휴대폰, Xbox, HoloLens 같은 기기에서 더 강력한 앱을 만들 수 있게 했지만, WPF와 함께 사용하는 완전한 .NET 앱보다는 여전히 기능이 제한적이었어요. 더 복잡한 건, WinRT와 UWP로만 만든 앱에게만 푸시 알림이나 라이브 타일, Microsoft Store 배포 같은 새로운 OS 레벨 기능과 통합을 허가했다는 겁니다. 이로 인해 개발자들 입장에선 정말 어색한 상황이 만들어졌습니다.