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

.NET Core/5+에서는 구할 수 없는 HttpRuntime.AppDomainAppId

AppDomainAppId는 System.Web.dll에 포함된 System.Web.HttpRuntime의 정적 속성으로,

HttpRuntime.AppDomainAppId Property
; https://docs.microsoft.com/en-us/dotnet/api/system.web.httpruntime.appdomainappid

IIS w3wp.exe에서 호스팅되는 경우 다음과 같은 유형으로 (AppPool이 아닌) 웹 애플리케이션의 고유 경로를 반환합니다.

/LM/W3C/<site id>/<servicename>

물론 다른 호스팅 환경에서는 저게 별 의미가 없지만, 그래도 IIS에서 활성화되는 경우라면 AppPool은 환경 변수를 통해 구할 수 있고, 그 AppPool에 활성화되는 Web Application의 고유 경로를 구할 수 있으므로 .NET Core/5+ 환경에서도 나름 의미가 있습니다.

문제는, HttpRuntime 클래스 자체가 오직 .NET Framework에서만 사용할 수 있다는 점입니다. .NET Core/5+에서는 BCL에서 누락됐으므로 당연히 그것과 관련된 모든 멤버를 사용할 수 없습니다. 이에 대해 아래의 답글을 보면,

AppDomainAppId in .NET Core?
; https://stackoverflow.com/questions/52891211/appdomainappid-in-net-core

HttpRuntime.cs 소스 코드로부터 AppDomainAppId의 값을 구하는 방법이 나옵니다.

_appDomainAppId = GetAppDomainString(".appId");

public static String AppDomainAppId 
{
    get { return _theRuntime._appDomainAppId; }
}

private static String GetAppDomainString(String key) 
{
    Object x = Thread.GetDomain().GetData(key);
 
    return x as String;
}

AppDomain 컨텍스트에 ".appId"라는 키로 값이 보관돼 있군요. 그나저나... 그럼 이 값은 언제 설정이 되는 걸까요? 아쉽게도 이것은 추적이 되지 않습니다. 나름대로 조사를 해봤는데, ".appId" 값이 설정되는 시기는 "PipelineRuntime.InitializeApplication" 호출이었는데요, 이때의 호출 스택을 보면 .NET Framework이 아닌 Native DLL에서 호출되고 있습니다.

>    System.Web.dll!System.Web.Hosting.PipelineRuntime.InitializeApplication(System.IntPtr appContext)   Unknown Non-user code. Skipped loading symbols.
    [AppDomain Transition]      Annotated Frame
    [Native to Managed Transition]      Annotated Frame
    webengine4.dll!W3_MGD_APP_CONTEXT::InitializeMgdApplication(void)   Unknown Non-user code. Symbols loaded.
    webengine4.dll!W3_MGD_APP_CONTEXT::OnApplicationResolveModules(class IHttpApplicationResolveModulesProvider *,void *)   Unknown Non-user code. Symbols loaded.
    webengine4.dll!CMgdEngGlobalModule::OnGlobalApplicationResolveModules(class IHttpApplicationResolveModulesProvider *)   Unknown Non-user code. Symbols loaded.
    iiscore.dll!W3_SERVER::GlobalNotify()   Unknown Non-user code. Symbols loaded.
    iiscore.dll!W3_APPLICATION::ResolveModules(void)    Unknown Non-user code. Symbols loaded.
    iiscore.dll!W3_APPLICATION::SetupNotificationContext()  Unknown Non-user code. Symbols loaded.
    iiscore.dll!W3_CONTEXT::SetupStateMachinePhase2()   Unknown Non-user code. Symbols loaded.
    iiscore.dll!W3_CONTEXT::SetupStateMachine() Unknown Non-user code. Symbols loaded.
    iiscore.dll!W3_MAIN_CONTEXT::OnNewRequest() Unknown Non-user code. Symbols loaded.
    w3dt.dll!UL_RECEIVE_CONTEXT::DoWork()   Unknown Non-user code. Symbols loaded.
    w3dt.dll!WP_CONTEXT::OnCompletion(unsigned long,unsigned long,struct _OVERLAPPED *) Unknown Non-user code. Symbols loaded.
    w3tp.dll!THREAD_POOL_DATA::ThreadPoolThread(void)   Unknown Non-user code. Symbols loaded.
    w3tp.dll!THREAD_POOL_DATA::ThreadPoolThread()   Unknown Non-user code. Symbols loaded.
    w3tp.dll!THREAD_MANAGER::ThreadManagerThread()  Unknown Non-user code. Symbols loaded.
    kernel32.dll!BaseThreadInitThunk() Unknown Non-user code. Symbols loaded.
    ntdll.dll!RtlUserThreadStart() Unknown Non-user code. Symbols loaded.

아마도 webengin4.dll이나 iiscore.dll 측에서 이미 AppDomain의 ".appId"를 설정하는 것으로 보입니다.

그 외에도 추적해 보면 System.Web.Hosting.ProcessHost.StartApplication 메서드가 불릴 때도 appId에 "/LM/W3C/<site id>/<servicename>" 형식의 ID 값이 전달되는데,

// System.Web!System.Web.Hosting.ProcessHost
public void StartApplication(string appId, string appPath, out object runtimeInterface)
{
        // ...[생략]...
        IApplicationHost applicationHost = this.CreateAppHost(appId, appPath);
        LockableAppDomainContext lockableAppDomainContext = this._appManager.GetLockableAppDomainContext(appId);
        // ...[생략]...
}

이것 역시도 호출 스택을 보면 PipelineRuntime.InitializeApplication처럼 webengine4.dll에서 호출이 됩니다. 그런 걸로 봤을 때, iis와 연동된 Native DLL 측에서 이미 AppDomainAppId에 해당하는 값이 구해졌고 어떤 식으로든 AppDomain 문맥 정보에 설정된 것으로 판단됩니다.

따라서, 굳이 AppDomainAppId 값을 구해야 한다면 현재 로딩된 응용 프로그램의 경로와 같은 여러 정황 단서를 이용해 ServerManager와 같은 개체를 활용해 직접 매칭되는 값을 구해오는 수밖에는 없습니다.

IIS Metabase와 ServerManager 개체 활용
; https://www.sysnet.pe.kr/2/0/973




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







[최초 등록일: ]
[최종 수정일: 7/19/2022]

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

비밀번호

댓글 작성자
 




... 31  [32]  33  34  35  36  37  38  39  40  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
13139정성태10/9/202213673.NET Framework: 2057. 리눅스 환경의 .NET Core 3/5+ 메모리 덤프로부터 모든 닷넷 모듈을 추출하는 방법파일 다운로드1
13138정성태10/8/202216266.NET Framework: 2056. C# - await 비동기 호출을 기대한 메서드가 동기로 호출되었을 때의 부작용 [1]
13137정성태10/8/202214220.NET Framework: 2055. 리눅스 환경의 .NET Core 3/5+ 메모리 덤프로부터 닷넷 모듈을 추출하는 방법
13136정성태10/7/202214547.NET Framework: 2054. .NET Core/5+ SDK 설치 없이 dotnet-dump 사용하는 방법
13135정성태10/5/202215067.NET Framework: 2053. 리눅스 환경의 .NET Core 3/5+ 메모리 덤프를 분석하는 방법 - 두 번째 이야기 [1]
13134정성태10/4/202212260오류 유형: 820. There is a problem with AMD Radeon RX 5600 XT device. For more information, search for 'graphics device driver error code 31'
13133정성태10/4/202213394Windows: 211. Windows - (commit이 아닌) reserved 메모리 사용량 확인 방법 [1]
13132정성태10/3/202213430스크립트: 42. 파이썬 - latexify-py 패키지 소개 - 함수를 mathjax 식으로 표현
13131정성태10/3/202217238.NET Framework: 2052. C# - Windows Forms의 데이터 바인딩 지원(DataBinding, DataSource) [2]파일 다운로드1
13130정성태9/28/202213051.NET Framework: 2051. .NET Core/5+ - 에러 로깅을 위한 Middleware가 동작하지 않는 경우파일 다운로드1
13129정성태9/27/202213674.NET Framework: 2050. .NET Core를 IIS에서 호스팅하는 경우 .NET Framework CLR이 함께 로드되는 환경
13128정성태9/23/202216605C/C++: 158. Visual C++ - IDL 구문 중 "unsigned long"을 인식하지 못하는 #import [1]파일 다운로드1
13127정성태9/22/202214860Windows: 210. WSL에 systemd 도입
13126정성태9/15/202215387.NET Framework: 2049. C# 11 - 정적 메서드에 대한 delegate 처리 시 cache 적용
13125정성태9/14/202215794.NET Framework: 2048. C# 11 - 구조체 필드의 자동 초기화(auto-default structs)
13124정성태9/13/202215587.NET Framework: 2047. Golang, Python, C#에서의 CRC32 사용
13123정성태9/8/202215636.NET Framework: 2046. C# 11 - 멤버(속성/필드)에 지정할 수 있는 required 예약어 추가
13122정성태8/26/202216043.NET Framework: 2045. C# 11 - 메서드 매개 변수에 대한 nameof 지원
13121정성태8/23/202212460C/C++: 157. Golang - 구조체의 slice 필드를 Reflection을 이용해 변경하는 방법
13120정성태8/19/202216070Windows: 209. Windows NT Service에서 UI를 다루는 방법 [3]
13119정성태8/18/202215177.NET Framework: 2044. .NET Core/5+ 프로젝트에서 참조 DLL이 보관된 공통 디렉터리를 지정하는 방법
13118정성태8/18/202212712.NET Framework: 2043. WPF Color의 기본 색 영역은 (sRGB가 아닌) scRGB [2]
13117정성태8/17/202216397.NET Framework: 2042. C# 11 - 파일 범위 내에서 유효한 타입 정의 (File-local types)파일 다운로드1
13116정성태8/4/202216847.NET Framework: 2041. C# - Socket.Close 시 Socket.Receive 메서드에서 예외가 발생하는 문제파일 다운로드1
13115정성태8/3/202217445.NET Framework: 2040. C# - ValueTask와 Task의 성능 비교 [1]파일 다운로드1
13114정성태8/2/202217298.NET Framework: 2039. C# - Task와 비교해 본 ValueTask 사용법파일 다운로드1
... 31  [32]  33  34  35  36  37  38  39  40  41  42  43  44  45  ...