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

비밀번호

댓글 작성자
 




... 46  47  48  49  50  51  52  [53]  54  55  56  57  58  59  60  ...
NoWriterDateCnt.TitleFile(s)
12326정성태9/12/20209959개발 환경 구성: 516. Azure VM의 Network Adapter를 실수로 비활성화한 경우
12325정성태9/12/20209562개발 환경 구성: 515. OpenVPN - 재부팅 후 ICS(Internet Connection Sharing) 기능이 동작 안하는 문제
12324정성태9/11/202010843개발 환경 구성: 514. smigdeploy.exe를 이용한 Windows Server 2016에서 2019로 마이그레이션 방법
12323정성태9/11/20209753오류 유형: 649. Copy Database Wizard - The job failed. Check the event log on the destination server for details.
12322정성태9/11/202010966개발 환경 구성: 513. Azure VM의 RDP 접속 위치 제한 [1]
12321정성태9/11/20209027오류 유형: 648. netsh http add urlacl - Error: 183 Cannot create a file when that file already exists.
12320정성태9/11/202010176개발 환경 구성: 512. RDP(원격 데스크톱) 접속 시 비밀 번호를 한 번 더 입력해야 하는 경우
12319정성태9/10/20209972오류 유형: 647. smigdeploy.exe를 Windows Server 2016에서 실행할 때 .NET Framework 미설치 오류 발생
12318정성태9/9/20209396오류 유형: 646. OpenVPN - "TAP-Windows Adapter V9" 어댑터의 "Network cable unplugged" 현상
12317정성태9/9/202011748개발 환경 구성: 511. Beats용 Kibana 기본 대시 보드 구성 방법
12316정성태9/8/202010152디버깅 기술: 170. WinDbg Preview 버전부터 닷넷 코어 3.0 이후의 메모리 덤프에 대해 sos.dll 자동 로드
12315정성태9/7/202012475개발 환경 구성: 510. Logstash - FileBeat을 이용한 IIS 로그 처리 [2]
12314정성태9/7/202011127오류 유형: 645. IIS HTTPERR - Timer_MinBytesPerSecond, Timer_ConnectionIdle 로그
12313정성태9/6/202012205개발 환경 구성: 509. Logstash - 사용자 정의 grok 패턴 추가를 이용한 IIS 로그 처리
12312정성태9/5/202016071개발 환경 구성: 508. Logstash 기본 사용법 [2]
12311정성태9/4/202011326.NET Framework: 937. C# - 간단하게 만들어 보는 리눅스의 nc(netcat), json_pp 프로그램 [1]
12310정성태9/3/202010595오류 유형: 644. Windows could not start the Elasticsearch 7.9.0 (elasticsearch-service-x64) service on Local Computer.
12309정성태9/3/202010342개발 환경 구성: 507. Elasticsearch 6.6부터 기본 추가된 한글 형태소 분석기 노리(nori) 사용법
12308정성태9/2/202011619개발 환경 구성: 506. Windows - 단일 머신에서 단일 바이너리로 여러 개의 ElasticSearch 노드를 실행하는 방법
12307정성태9/2/202012355오류 유형: 643. curl - json_parse_exception / Invalid UTF-8 start byte
12306정성태9/1/202010495오류 유형: 642. SQL Server 시작 오류 - error code 10013
12305정성태9/1/202011410Windows: 172. "Administered port exclusions"이 아닌 포트 범위 항목을 삭제하는 방법
12304정성태8/31/202010341개발 환경 구성: 505. 윈도우 - (네트워크 어댑터의 우선순위로 인한) 열거되는 IP 주소 순서를 조정하는 방법
12303정성태8/30/202010553개발 환경 구성: 504. ETW - 닷넷 프레임워크 기반의 응용 프로그램을 위한 명령행 도구 etrace 소개
12302정성태8/30/202010438.NET Framework: 936. C# - ETW 관련 Win32 API 사용 예제 코드 (5) - Private Logger파일 다운로드1
12301정성태8/30/202010755오류 유형: 641. error MSB4044: The "Fody.WeavingTask" task was not given a value for the required parameter "IntermediateDir".
... 46  47  48  49  50  51  52  [53]  54  55  56  57  58  59  60  ...