Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

iisreset 후에도 이전에 설정한 전역 환경 변수가 w3wp.exe에 적용되는 문제

윈도우 운영체제에서 전역 환경 변수는 다음의 레지스트리 경로에 설정할 수 있습니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

가령 저 경로에 REG_SZ 유형으로 "TEST"라는 이름의 환경 변수를 "1"로 새롭게 생성했다고 가정해 보겠습니다. 이러한 변화는 현재 실행 중인 프로세스들에게는 알려지지 않습니다. 그리고 이전 글에서 설명한 방법으로 그 목적은 달성할 수 있습니다.

C# - 환경 변수의 변화를 알리는 WM_SETTINGCHANGE Win32 메시지 사용법
; https://www.sysnet.pe.kr/2/0/13027

만약, 저 메시지 수신을 대응하지 않는 프로세스라면, 어쩔 수 없이 프로세스를 다시 시작해야 하는 것입니다.

그런데, 여기서 한 가지 문제가 더 있습니다. 바로, 윈도우 운영체제에서 환경 변수는 부모 프로세스의 것을 물려받는다는 점입니다. 이것이 문제가 되는 대표적인 유형이 바로 웹 응용 프로그램을 호스팅하는 w3wp.exe입니다.

w3wp.exe 프로세스는 해당 EXE가 속한 Application Pool을 "재생(Recycle)"시키면 w3wp.exe 프로세스도 내려갔다가 다시 올라오는데요, 재미있는 것은 이때 레지스트리의 설정을 반영하지 못한다는 점입니다. 왜냐하면, 재생(Recycle) 작업은 IIS 서비스를 관리하는 svchost.exe 프로세스가 관장하는데, 이 때문에 w3wp.exe의 직계 부모 프로세스는 svchost.exe가 되고, 결국 svchost.exe의 환경 변수를 그대로 상속받기 때문입니다.

따라서, w3wp.exe의 환경 변수를 새롭게 반영하려면 그것의 부모 프로세스인 svchost.exe까지 완전히 내렸다가 다시 올리는 "iisreset" 명령어를 사용해야 합니다.

참고로, 서비스 관리자에 W3SVC(World Wide Web Publishing 서비스)라고 알려진 서비스를 재시작하면 svchost.exe가 아닌, 그 하위의 모든 w3wp.exe를 재시작하는 역할을 합니다. 즉, 특정 AppPool이 아닌, 모든 AppPool을 재생하는 것과 같은 역할입니다. 반면, "WAS(Windows Process Activation Service)" 서비스를 재시작하면 svchost.exe까지 재시작하는 효과를 갖는데 사실상 iisreset과 유사합니다.




그런데, 간혹 특정 PC에서는 iisreset을 해도 여전히 이전과 동일한 환경 변수를 유지하는 경우가 있습니다. 재현은 다음과 같이 해볼 수 있습니다.

  1. 전역 환경 설정에 TEST=1을 설정
  2. iisreset
  3. 새롭게 설정한 TEST=1 환경 변수는 w3wp.exe에 적용됨
  4. 전역 환경 설정에서 TEST=1을 제거
  5. iisreset
  6. 새롭게 시작한 w3wp.exe에는 여전히 TEST=1 환경 변수가 존재

즉, 전역 환경 설정에서 제거한 TEST=1 환경 변수가 (재부팅하기 전까지는) 삭제되지 않는 것입니다.

이때의 (WAS 서비스인) svchost.exe 프로세스를 Process Explorer를 통해 확인해 보면 그 프로세스 자체에서 이미 환경 변수의 반영이 안 되었다는 것을 알 수 있습니다.

어떻게 생각하면, svchost.exe 역시 그 상위의 프로세스, 즉 SCM(Service Control Manager)이라는 NT 서비스 관리자 프로세스 역할을 하는 services.exe 프로세스 때문이라고 볼 수도 있습니다.

즉, services.exe는 전역 환경 변수가 바뀐 이후 재실행하지 않았으므로 여전히 기존 환경 변수를 보유하고 있으며, 그 상태에서 하위 프로세스인 (WAS를 호스팅하는) svchost.exe를 재시작하는 것이므로 services.exe의 환경 변수를 그대로 상속받게 되는 것입니다.

여기서 재미있는 것은, 일반적인 컴퓨터에서는 저런 상황이 발생하지 않습니다. 정확한 문서를 확인한 것은 아니지만, 마이크로소프트는 services.exe의 경우 하위 프로세스를 실행할 때 1) 환경 변수를 상속하지 않도록 만들거나, 2) 전역 환경 변수의 변화를 받아들이는 식의 작업이 되어 있는 것처럼 동작합니다.

실제로, 대부분의 PC에서 iisreset을 하면 services.exe의 환경 변수에 상관없이 전역 환경 변수 레지스트리의 변화를 반영해 (WAS 서비스인) svchost.exe가 실행이 됩니다.

그런데, 유독 특정 PC에서만 ^^; 그 동작을 하지 않고 있는 것입니다.




이 문제를 다른 식으로 재현해 볼까요? ^^

여기서 해당 svchost.exe는 Local SYSTEM 권한으로 동작하는데요, 실제로 일반 프로세스를 그 권한으로 실행해 보면,

c:\temp> psexec -s -i cmd.exe /K set

svchost.exe가 가지고 있던 환경 변수가 그대로 동일하게 cmd.exe에도 적용된 것을 확인할 수 있습니다.

여기서 더욱 재미있는 것은, iisreset 명령어는 다음의 실행 파일을 구동하는 것에 불과한데,

C:\Windows\System32\inetsrv\iisrstas.exe

이때 iisrstas.exe 프로세스의 부모 프로세스는 (services.exe를 부모로 둔) DcomLaunch 서비스를 대행하는 svchost.exe이고, 그것 역시 예전 환경 변수 구성을 담고 있지만 iisrstas.exe 프로세스를 Process Explorer로 확인해 보면 (w3wp.exe와는 달리) 새롭게 변경된 전역 환경 변수 구성을 반영하고 있다는 점입니다.

물론, 차이점은 있습니다. 실행된 iisrstas.exe의 "USERNAME"은 (iisreset을 관리자 권한으로 실행하므로) Administrator인 반면, w3wp.exe의 부모인 svchost.exe는 Local SYSTEM이라는 것입니다.

그러니까, 사용자 계정 권한에 따라 Local SYSTEM 환경에서는 (레지스트리에 설정된) 새로운 전역 환경 변수 설정을 반영하지 못하고 있는 것입니다. 정리해 보면, services.exe가 환경 변수를 정상적으로 처리하지 못하는 것은 아닌 듯하고, 단지 Local SYSTEM 계정으로 실행되는 프로세스가 정상적으로 환경 변수를 적용하지 못하는 것입니다.




일단, 이 문제의 해결책은 저도 모르겠습니다. ^^; 모든 윈도우 PC가 그런 것도 아니고, 몇몇 사례에서만 이런 현상이 발생하고 있는데 약간의 특이점이라면 최근에 저 현상을 접한 윈도우 PC가 AhnLab이 설치되어 있다는 정도입니다. 앞으로 또 유사한 사례가 나오면 환경 구성을 유심히 봐야겠습니다. ^^;

단지, 우회 방법 정도는 살펴볼 수 있습니다. 위에서 제가 언급한 TEST=1 변수가 삭제되지 않는 문제는, LOCAL SYSTEM 전용 레지스트리의 경로에서,

Computer\HKEY_USERS\S-1-5-18\Environment

TEST 환경 변수를 정의하고 값만 설정해 두지 않으면 됩니다. 즉, iisreset 후 생성되는 w3wp.exe 프로세스가 저 레지스트리의 환경 변수는 정상적으로 반영해서 올라오는 것입니다.

저 방법을 쓰는 것이 하나 껄끄러운 점이 있다면, 저런 조치를 취했다는 것을 행여 잊어버린다거나 하면, 이후 "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" 환경 변수에 TEST=1을 설정해도 Local SYSTEM 계정의 프로세스에만 절대로 반영이 안 되는 것 같은 (당연하지만) 희한한 현상을 겪을 수 있다는 점입니다.




참고로, 다른 프로세스의 환경 변수 설정을 코드로 해결하는 방법은 예전에 설명한 적이 있습니다. ^^

Appinit_Dlls로 구현한 환경 변수 설정 DLL
; https://www.sysnet.pe.kr/2/0/883




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 11/21/2022]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 151  152  153  154  155  156  157  [158]  159  160  161  162  163  164  165  ...
NoWriterDateCnt.TitleFile(s)
1099정성태8/15/201128257오류 유형: 132. 어느 순간 갑자기 접속이 안 되는 TFS 서버
1098정성태8/15/201150339웹: 24. 네이버는 어떻게 로그인 처리를 할까요? [2]
1097정성태8/15/201121640.NET Framework: 235. 메서드의 메타 데이터 토큰 값으로 클래스를 찾아내는 방법
1096정성태8/15/201125772디버깅 기술: 42. Watson Bucket 정보를 이용한 CLR 응용 프로그램 예외 분석 - (2)
1095정성태8/14/201126158디버깅 기술: 41. Windbg - 비정상 종료된 닷넷 프로그램의 StackTrace에서 보이는 offset 값 의미
1094정성태8/14/201130604오류 유형: 131. Fiddler가 강제 종료된 경우, 웹 사이트 방문이 안되는 현상
1093정성태7/27/201124180오류 유형: 130. Unable to connect to the Microsoft Visual Studio Remote Debugging Monitor ... Access is denied.
1092정성태7/22/201126625Team Foundation Server: 46. 코드 이외의 파일에 대해 소스 제어에서 제외시키는 방법
1091정성태7/21/201125657개발 환경 구성: 128. WP7 Emulator 실행 시 audiodg.exe의 CPU 소모율 증가 [2]
1089정성태7/18/201131229.NET Framework: 234. 왜? Button 컨트롤에는 MouseDown/MouseUp 이벤트가 발생하지 않을까요?파일 다운로드1
1088정성태7/16/201124254.NET Framework: 233. Entity Framework 4.1 - 윈도우 폰 7에서의 CodeFirst 순환 참조 문제파일 다운로드1
1087정성태7/15/201126999.NET Framework: 232. Entity Framework 4.1 - CodeFirst 개체의 직렬화 시 순환 참조 해결하는 방법 - 두 번째 이야기파일 다운로드1
1086정성태7/14/201128372.NET Framework: 231. Entity Framework 4.1 - CodeFirst 개체의 직렬화 시 순환 참조 해결하는 방법 [1]파일 다운로드1
1085정성태7/14/201128890.NET Framework: 230. Entity Framework 4.1 - Code First + WCF 서비스 시 EndpointNotFoundException 오류 - 두 번째 이야기파일 다운로드1
1084정성태7/11/201134159.NET Framework: 229. SQL 서버 - DB 테이블의 데이터 변경에 대한 알림 처리 [4]파일 다운로드1
1083정성태7/11/201128205.NET Framework: 228. Entity Framework 4.1 - Code First + WCF 서비스 시 EndpointNotFoundException 오류
1082정성태7/10/201127743.NET Framework: 227. basicHttpBinding + 사용자 정의 인증 구현 [2]파일 다운로드1
1081정성태7/9/201127075VC++: 53. Windows 7에서 gcc.exe 실행 시 Access denied 오류 [2]
1080정성태7/8/201125584웹: 23. Sysnet 웹 사이트의 HTML5 변환 기록 - 두 번째 이야기파일 다운로드1
1079정성태7/6/201130005오류 유형: 129. Hyper-V + Realtek 랜카드가 설치된 시스템의 BSOD 현상 [2]
1078정성태7/5/201137478VC++: 52. Chromium 컴파일하는 방법 [2]
1077정성태6/24/201135106.NET Framework: 226. HttpWebRequest 타입의 HaveResponse 속성 이야기파일 다운로드1
1076정성태6/23/201129297오류 유형: 128. SQL Express - User Instance 옵션을 사용한 경우 발생하는 오류 메시지 유형 2가지
1075정성태6/21/201124862VS.NET IDE: 69. 윈폰 프로젝트에서 WCF 서비스 참조할 때 Reference.cs 파일이 비어있는 경우
1074정성태6/20/201124987.NET Framework: 225. 닷넷 네트워크 라이브러리의 트레이스 기능파일 다운로드1
1073정성태6/20/201127213오류 유형: 127. Visual Studio에서 WCF 서비스의 이름 변경 시 발생할 수 있는 오류
... 151  152  153  154  155  156  157  [158]  159  160  161  162  163  164  165  ...