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

비밀번호

댓글 작성자
 




... 121  122  123  124  125  126  127  128  129  [130]  131  132  133  134  135  ...
NoWriterDateCnt.TitleFile(s)
1805정성태11/5/201421905.NET Framework: 476. Visual Studio에서 Mono용 Profiler 개발 [3]파일 다운로드1
1804정성태11/5/201428125.NET Framework: 475. ETW(Event Tracing for Windows)를 C#에서 사용하는 방법 [9]파일 다운로드1
1803정성태11/4/201420228오류 유형: 261. Windows Server Backup 오류 - Error in backup of E:\$Extend\$RmMetadata\$TxfLog
1802정성태11/4/201422213오류 유형: 260. 이벤트 로그 - Windows Error Reporting / AEAPPINVW8
1801정성태11/4/201427486오류 유형: 259. 이벤트 로그 - Windows Error Reporting / IPX Assertion / KorIME.exe [1]
1800정성태11/4/201418223오류 유형: 258. 이벤트 로그 - Starting a SMART disk polling operation in Automatic mode.
1799정성태11/4/201423015오류 유형: 257. 이벤트 로그 - The WMI Performance Adapter service entered the stopped state.
1798정성태11/4/201431772오류 유형: 256. 이벤트 로그 - The WinHTTP Web Proxy Auto-Discovery Service service entered the stopped state. [1]
1797정성태11/4/201417432오류 유형: 255. 이벤트 로그 - The Adobe Flash Player Update Service service entered the stopped state.
1796정성태10/30/201424487개발 환경 구성: 249. Visual Studio 2013에서 Mono 컴파일하는 방법
1795정성태10/29/201426983개발 환경 구성: 248. Lync 2013 서버 설치 방법
1794정성태10/29/201422474개발 환경 구성: 247. "Microsoft Office 365 Enterprise E3" 서비스에 대한 간략 소개
1793정성태10/27/201423068.NET Framework: 474. C# - chromiumembedded 사용 - 두 번째 이야기 [2]파일 다운로드1
1792정성태10/27/201423255.NET Framework: 473. WebClient 객체에 쿠키(Cookie)를 사용하는 방법
1791정성태10/22/201422961VC++: 83. G++ - 템플릿 클래스의 iterator 코드 사용에서 발생하는 컴파일 오류 [5]
1790정성태10/22/201418502오류 유형: 254. NETLOGON Service is paused on [... AD Server...]
1789정성태10/22/201421141오류 유형: 253. 이벤트 로그 - The client-side extension could not remove user policy settings for '...'
1788정성태10/22/201423186VC++: 82. COM 프로그래밍에서 HRESULT 타입의 S_FALSE는 실패일까요? 성공일까요? [2]
1787정성태10/22/201431362오류 유형: 252. COM 개체 등록시 0x8002801C 오류가 발생한다면?
1786정성태10/22/201432654디버깅 기술: 65. 프로세스 비정상 종료 시 "Debug Diagnostic Tool"를 이용해 덤프를 남기는 방법 [3]파일 다운로드1
1785정성태10/22/201421921오류 유형: 251. 이벤트 로그 - Load control template file /_controltemplates/TaxonomyPicker.ascx failed [1]
1784정성태10/22/201430003.NET Framework: 472. C/C++과 C# 사이의 메모리 할당/해제 방법파일 다운로드1
1783정성태10/21/201423366VC++: 81. 프로그래밍에서 borrowing의 개념
1782정성태10/21/201420106오류 유형: 250. 이벤트 로그 - Application Server job failed for service instance Microsoft.Office.Server.Search.Administration.SearchServiceInstance
1781정성태10/21/201420516디버깅 기술: 64. new/delete의 짝이 맞는 경우에도 메모리 누수가 발생한다면?
1780정성태10/15/201424194오류 유형: 249. The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID
... 121  122  123  124  125  126  127  128  129  [130]  131  132  133  134  135  ...