---
title: "윈도우 95 시절 쉘 API로 만든 명령줄 도구, WinUtils 회고"
published: 2026-06-02T22:33:02.000Z
canonical: https://jeff.news/article/3661
---
# 윈도우 95 시절 쉘 API로 만든 명령줄 도구, WinUtils 회고

글쓴이가 1996~1997년에 만든 WinUtils는 윈도우 95의 쉘 API를 감싼 얇은 명령줄 도구 모음이었다. 직접 파일 입출력을 구현하는 대신 탐색기와 같은 복사, 이동, 삭제, 휴지통, 확인창 동작을 그대로 활용한 점이 핵심이다.

- WinUtils는 1996~1997년쯤 글쓴이가 윈도우 95 쉘 API를 공부하면서 만든 명령줄 도구 모음임
  - 목표는 직접 파일 입출력을 구현하는 게 아니라, 윈도우 쉘이 이미 제공하는 파일 작업 함수를 명령줄에서 부르는 것이었음
  - 덕분에 탐색기에서 보던 확인창, 진행창, 휴지통 동작을 거의 그대로 가져올 수 있었음

- 핵심은 “내가 다 만들지 않고 운영체제가 잘하는 걸 얇게 감싼다”는 설계였음
  - SHFileOperation이 복사, 이동, 삭제, 이름 변경의 중심 API였음
  - SHFILEOPSTRUCT로 원본과 대상 경로, 플래그를 넘겼음
  - FO_COPY, FO_DELETE, FO_MOVE, FO_RENAME 같은 작업 코드가 각 유틸리티에 대응됨
  - SHGetFileInfo는 탐색기와 맞는 아이콘이나 표시 이름을 가져올 때 썼음

> [!TIP]
> 작은 도구라도 운영체제 기본 동작에 올라타면 사용자가 기대하는 안전장치와 사용자 경험을 같이 얻을 수 있음.

- 가장 실용적인 장점은 되돌리기였음
  - windel로 지운 파일은 FOF_ALLOWUNDO 플래그 덕분에 휴지통으로 들어감
  - winmove를 잘못 실행해도 탐색기에서 일반 파일 작업처럼 되돌릴 수 있었음
  - 명령줄 도구인데도 윈도우 사용자에게 익숙한 안전망을 제공했다는 게 꽤 맛있는 포인트임

- 도구 구성은 단순했지만 스위치는 쉘 플래그와 거의 1대1로 이어졌음
  - wincopy와 winmove는 원본과 대상, 그리고 여러 단일 문자 스위치를 받음
  - windel은 삭제 도구라 충돌 이름 변경 스위치가 빠짐
  - winren은 이름 변경에 필요한 /a, /h, /r, /u 정도만 남김
  - /n은 확인 없이 진행, /r은 충돌 시 이름 변경, /s는 진행창 없이 조용히 실행, /u는 휴지통 기반 되돌리기를 의미함

- 당시에는 실행 파일에 커스텀 아이콘을 붙이는 것만으로도 프로젝트가 완성된 느낌이었다고 함
  - 글쓴이는 기존 윈도우 아이콘 조각을 편집기로 이어 붙여 각 유틸리티 아이콘을 만들었음
  - 완전히 독창적인 아트는 아니었지만, 각 실행 파일에 정체성을 부여하는 작업이었음

- 도움말 파일 만들기는 작은 유틸리티치고 꽤 빡센 별도 프로젝트였음
  - /h 스위치는 winutils.hlp를 열었음
  - 당시 윈도우 도움말은 RTF로 토픽을 쓰고, HPJ 프로젝트 파일과 CNT 목차 파일을 만들고, Help Compiler로 HLP 바이너리를 생성해야 했음
  - 교차 참조와 팝업 정의는 RTF 안의 각주 코드로 달았고, 잘못 맞추면 엉뚱한 도움말 토픽이 열리기도 했음

- 배포도 지금과 완전히 다른 세계였음
  - 앱스토어, 깃허브 릴리스, 패키지 배포 같은 건 없었음
  - 실행 파일과 도움말을 압축해서 Tucows, Download.com, WinSite, ZDNet 같은 셰어웨어 사이트에 올리는 식이었음
  - 피드백은 각 사이트에 다시 접속해서 다운로드 카운터가 올라갔는지 보는 정도였고, 그 숫자 하나가 꽤 큰 보상이었다고 함

- 글쓴이는 지금이라면 대규모 언어 모델(LLM)이 WinUtils 전체를 몇 분 만에 재현할 수 있을 거라고 인정함
  - 소스, 스위치, 도움말, 아이콘까지 자동으로 만들 수 있는 시대라는 것
  - 하지만 당시의 비효율적인 고생, 종이 문서로 API를 읽고 플래그를 추측하고 도움말 컴파일러와 싸우던 경험이 진짜 학습이었다고 말함
  - 결론은 살짝 아재 개발 회고인데, 꽤 공감됨. 빨리 만드는 것과 몸에 남는 것은 다른 문제임

---

## 기술 맥락

- WinUtils의 선택은 파일 작업을 직접 구현하지 않고 윈도우 쉘 API를 호출하는 거였어요. 복사와 삭제를 직접 짜면 예외 처리가 많아지는데, 쉘을 타면 탐색기와 같은 확인창, 진행창, 휴지통 동작을 그대로 얻을 수 있거든요.

- 특히 FOF_ALLOWUNDO가 중요한 이유는 명령줄 도구에 되돌리기 감각을 넣어줬기 때문이에요. 일반적인 삭제 명령은 실수하면 끝이라는 느낌이 강한데, 이 방식은 사용자가 탐색기에서 복구할 수 있는 여지를 남겨요.

- 도움말 시스템도 당시 윈도우 앱 배포의 일부였어요. RTF와 HPJ, CNT를 맞춰 컴파일해야 했기 때문에 지금의 README 하나보다 훨씬 번거로웠고, 작은 도구라도 문서화와 배포 포맷을 신경 써야 했어요.

- 이 글이 지금도 재미있는 건 자동화가 낮춘 진입장벽과 직접 부딪히며 얻는 이해를 같이 보여주기 때문이에요. 대규모 언어 모델이 코드를 빨리 만들어줘도, 운영체제 API가 왜 그런 모양인지 이해하는 경험은 여전히 따로 필요해요.

## 핵심 포인트

- WinUtils는 SHFileOperation을 호출해 복사, 이동, 삭제, 이름 변경을 처리했다
- 휴지통 기반 되돌리기는 FOF_ALLOWUNDO 플래그 덕분에 가능했다
- 도움말 파일은 RTF, HPJ, CNT, Help Compiler를 거쳐 만드는 꽤 번거로운 작업이었다
- 글쓴이는 비효율적인 시행착오가 오히려 오래 남는 학습 경험이었다고 회고한다

## 인사이트

요즘이라면 대규모 언어 모델이 몇 분 만에 비슷한 코드를 뽑아낼 수 있겠지만, 이 글의 재미는 ‘고생이 학습의 일부였다’는 대목이다. 얇은 래퍼라도 운영체제의 사용자 경험을 존중하면 꽤 쓸모 있는 도구가 된다는 교훈도 있다.
