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

비밀번호

댓글 작성자
 




... 91  92  93  94  95  96  97  98  99  100  101  102  103  [104]  105  ...
NoWriterDateCnt.TitleFile(s)
11325정성태10/14/201719319.NET Framework: 689. CLR 4.0 환경에서 DLL 모듈의 로드 주소(Base address) 알아내는 방법
11324정성태10/13/201720908디버깅 기술: 101. windbg - "*** WARNING: Unable to verify checksum for" 경고 없애는 방법
11322정성태10/13/201718299디버깅 기술: 100. windbg - .NET 4.0 응용 프로그램의 Main 메서드에 Breakpoint 걸기
11321정성태10/11/201719815.NET Framework: 688. NGen 모듈과 .NET Profiler
11320정성태10/11/201720611.NET Framework: 687. COR_PRF_USE_PROFILE_IMAGES 옵션과 NGen의 "profiler-enhanced images" [1]
11319정성태10/11/201728176.NET Framework: 686. C# - string 배열을 담은 구조체를 직렬화하는 방법
11318정성태10/7/201720942VS.NET IDE: 122. 비주얼 스튜디오에서 관리자 권한을 요구하는 C# 콘솔 프로그램 제작 [1]
11317정성태10/4/201726115VC++: 120. std::copy 등의 함수 사용 시 _SCL_SECURE_NO_WARNINGS 에러 발생
11316정성태9/30/201724168디버깅 기술: 99. (닷넷) 프로세스(EXE)에 디버거가 연결되어 있는지 아는 방법 [4]
11315정성태9/29/201740244기타: 68. "시작하세요! C# 6.0 프로그래밍: 기본 문법부터 실전 예제까지" 구매하신 분들을 위한 C# 7.0/7.1 추가 문법 PDF [8]
11314정성태9/28/201722029디버깅 기술: 98. windbg - 덤프 파일로부터 닷넷 버전 확인하는 방법
11313정성태9/25/201719317디버깅 기술: 97. windbg - 메모리 덤프로부터 DateTime 형식의 값을 알아내는 방법파일 다운로드1
11312정성태9/25/201722435.NET Framework: 685. C# - 구조체(값 형식)의 필드를 리플렉션을 이용해 값을 바꾸는 방법파일 다운로드1
11311정성태9/20/201716845.NET Framework: 684. System.Diagnostics.Process 객체의 명시적인 해제 권장
11310정성태9/19/201720278.NET Framework: 683. WPF의 Window 객체를 생성했는데 GC 수집 대상이 안 되는 이유 [3]
11309정성태9/13/201718399개발 환경 구성: 335. Octave의 명령 창에서 실행한 결과를 복사하는 방법
11308정성태9/13/201719443VS.NET IDE: 121. 비주얼 스튜디오에서 일부 텍스트 파일을 무조건 메모장으로만 여는 문제파일 다운로드1
11307정성태9/13/201721978오류 유형: 421. System.Runtime.InteropServices.SEHException - 0x80004005
11306정성태9/12/201720049.NET Framework: 682. 아웃룩 사용자를 위한 중국어 스팸 필터 Add-in
11305정성태9/12/201721532개발 환경 구성: 334. 기존 프로젝트를 Visual Studio를 이용해 Github의 신규 생성된 repo에 올리는 방법 [1]
11304정성태9/11/201718654개발 환경 구성: 333. 3ds Max를 Hyper-V VM에서 실행하는 방법
11303정성태9/11/201721960개발 환경 구성: 332. Inno Setup 파일의 관리자 권한을 제거하는 방법
11302정성태9/11/201718186개발 환경 구성: 331. SQL Server Express를 위한 방화벽 설정
11301정성태9/11/201717091오류 유형: 420. SQL Server Express 연결 오류 - A network-related or instance-specific error occurred while establishing a connection to SQL Server.
11300정성태9/10/201720965.NET Framework: 681. dotnet.exe - run, exec, build, restore, publish 차이점 [3]
11299정성태9/9/201719694개발 환경 구성: 330. Hyper-V VM의 Internal Network를 Private 유형으로 만드는 방법
... 91  92  93  94  95  96  97  98  99  100  101  102  103  [104]  105  ...