(사용 중이어서 잠긴 파일도 놀랍게도 rename과 같은 드라이브 안의 이동은 가능하다. 단지 드라이브 바깥으로의 이동이나 삭제, 교체, 덮어쓰기가 안 될 뿐이다.)
이 분야에 관한 한 윈도우 API는 무척 자비심이 없었다. 윈도우 NT 계열과 9x 계열이 설정하는 방법이 서로 완전히 달랐기 때문이다.
전자의 경우 MoveFileEx라는 걸출한 API가 있어서 MOVEFILE_DELAY_UNTIL_REBOOT 플래그만 지정해 주면 됐다. 다음 재부팅 때 교체/삭제될 예정인 파일 목록은 레지스트리에 별도로 관리되는데, 이 위치 역시 MSDN에 문서화돼 있다.
이게 제일 깔끔한 방법인 반면 윈도우 9x에서는 이 방법을 쓸 수 없다.
윈도우 9x는 부팅 직전에 업데이트 또는 삭제해야 하는 파일의 리스트를 윈도우 디렉토리에 있는 wininit.ini 파일로부터 읽는다. 거기에 뭔가 의미 있는 값이 있다면, 바로 그 때 “Windows가 일부 구성요소를 업데이트하고 있습니다. 몇 분 정도 시간이 소요될 수 있습니다”란 친근한 메시지를 부팅 중에 텍스트 모드에서 영어로 잠시 보여준다. 아마 9x 유저들은 이 메시지를 기억할 것이다.
이 처리를 다 마치고 나면 wininit.ini 파일은 wininit.bak로 개명된다.
이 일을 하는 프로그램은 wininit.exe라는 프로그램이다. 그런데 얘는 본격적인 32비트 운영체제가 로딩되기 전에 잠깐 실행되는 완벽한 16비트 도스용 프로그램일 뿐이다. 그래서 wininit.ini 리스트에는 긴 파일 이름(LFN)을 쓸 수 없다는 무지하게 불편한 제약이 걸린다. 파일 이름이야 그렇다 치지만 폴더 이름까지 공백 하나 표현 못하니 얼마나 불편하리요.
지울 때야 LONGFI~1.TXT 이렇게 지정하면 되겠지만 옛 파일을 LFN 방식의 새 파일로 깔끔하게 교체하는 건 불가능하다는 뜻이기도 하다. 정 하고 싶으면 rename을 부팅 때 강제로 해 주는 다른 프로그램을 RunOnce 이런 레지스트리에 넣기라도 해야 한다.
또 하나 고려할 만한 점으로..
인스톨러가 프로그램을 설치/제거하다가 일부 파일을 건드리지 못했다면 “다음 프로그램이 이 파일을 사용 중입니다” 이러면서 파일을 사용 중인 프로그램 나열까지 띄워 주면 무척 좋을 것이다. (MSI는 실제로 그렇게 해 주고 있다.)
이 기능을 직접 구현하려면 현재 로딩되어 있는 모듈(EXE/DLL)의 리스트를 얻어 오는 API를 써야 하는데 이 역시 윈도우 9x와 NT가 사용하는 API 계보가 완전히 달랐다. 전자는 ToolHelp라고 불렸고 후자는 Process Status API였는데 다행히 윈도우 2000에는 9x의 ToolHelp API도 추가되어서 API가 일종의 통합을 이뤘다.
한편, 저런 이유 때문에 일부 파일을 결국 교체나 삭제를 못 한 경우 인스톨러는 “작업을 완료하려면 재부팅이 필요합니다. 지금 하시겠습니까?”라고 묻는 게 일반적이다. 하지만 대다수의 사용자는 귀차니즘에 입각하여 ‘아니요’를 고르고 만다.
그런데, 그렇게 재부팅을 미루고 언인스톨러를 종료했는데 그 상태에서 사용자가 그 프로그램을 다시 설치한 경우 꽤 문제가 된다. (변덕 한번 심하기도 하다. -_-)
잘 만들어진 인스톨러라면, 이 경우 교체하거나 삭제하기로 요청해 놓은 파일의 예약을 도로 취소해야 한다. 안 그러면 그렇게 재설치 한 후 다음에 운영체제를 재시작하는 순간 재앙이 벌어질 수도 있다.
따라서 원칙대로라면 건드리지 못한 파일이 없더라도 인스톨러는 wininit.ini 같은 목록을 뒤져 봐야 한다. 그것도 운영체제 계열 별로 완전히 다른 접근 방식으로 말이다. 요즘이야 9x 계열은 사실상 신경 쓸 필요도 없어지긴 했지만. 참고로 MSI가 저것까지 똑똑하게 알아서 처리해 주는지는 테스트 안 해 봤다.
결론은, 인스톨러는 완성도 높게 잘 만들려면 현 프로그램의 설치/제거 상태부터 시작해서, 저런 지저분한 API 차이까지 감안해 가며 귀찮게 따져야 하는 게 무지하게 많다는 것. IME 하나 만들려면 지저분한 잡일이 너무 많으니 MS에서 TSF를 개발한 것처럼, 저런 작업을 표준화하고 자동화하기 위해서 MSI라는 것을 안 만들 수가 없었을 것이다.
MSI는 파일을 복사하고 쓰는 제 본연의 기능 면에서 완성도는 무척 높은 것을 인정하지만, 같은 MS에서 개발한 AppLocale 같은 프로그램하고도 UI가 충돌을 일으킨다는 점은 심히 유감이다. -_-
Posted by 사무엘