Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 4개 있습니다.)
(시리즈 글이 5개 있습니다.)
.NET Framework: 1066. Wslhub.Sdk 사용으로 알아보는 CoInitializeSecurity 사용 제약
; https://www.sysnet.pe.kr/2/0/12665

.NET Framework: 1067. 별도 DLL에 포함된 타입을 STAThread Main 메서드에서 사용하는 경우 CoInitializeSecurity 자동 호출
; https://www.sysnet.pe.kr/2/0/12666

.NET Framework: 1068. COM+ 서버 응용 프로그램을 이용해 CoInitializeSecurity 제약 해결
; https://www.sysnet.pe.kr/2/0/12667

.NET Framework: 1071. DLL Surrogate를 이용한 Out-of-process COM 개체에서의 CoInitializeSecurity 문제
; https://www.sysnet.pe.kr/2/0/12670

COM 개체 관련: 23. CoInitializeSecurity의 전역 설정을 재정의하는 CoSetProxyBlanket 함수 사용법
; https://www.sysnet.pe.kr/2/0/12679




별도 DLL에 포함된 타입을 STAThread Main 메서드에서 사용하는 경우 CoInitializeSecurity 자동 호출

재미있는 현상이군요. ^^; 지난 글의 마지막에,

Wslhub.Sdk 사용으로 알아보는 CoInitializeSecurity 사용 제약
; https://www.sysnet.pe.kr/2/0/12665

다음의 코드를 .NET Framework 환경에서 수행하면 결괏값이 RPC_E_TOO_LATE가 나온다고 했는데요,

using System;
using WslSdk.Interop;

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        var result = NativeMethods.CoInitializeSecurity(
            IntPtr.Zero,
            (-1),
            IntPtr.Zero,
            IntPtr.Zero,
            NativeMethods.RpcAuthnLevel.None,
            NativeMethods.RpcImpLevel.Impersonate,
            IntPtr.Zero,
            NativeMethods.EoAuthnCap.StaticCloaking,
            IntPtr.Zero);

        Console.WriteLine(result); // 출력 결과: 0
    }
}

그런데, 실제로 저렇게 테스트해 보면 0이 나옵니다. 단지 영향이 없을 것 같은 코드를 저기에 싣지 않았던 것뿐인데요, 원래는 아래와 같았습니다.

using System;
using WslSdk.Interop;

// Install-Package Wslhub.Sdk
class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        var result = NativeMethods.CoInitializeSecurity(
            IntPtr.Zero,
            (-1),
            IntPtr.Zero,
            IntPtr.Zero,
            NativeMethods.RpcAuthnLevel.None,
            NativeMethods.RpcImpLevel.Impersonate,
            IntPtr.Zero,
            NativeMethods.EoAuthnCap.StaticCloaking,
            IntPtr.Zero);

        Console.WriteLine(result); // 출력 결과: -2147417831

        Wsl.GetDistroListFromRegistry();
    }
}

그러니까, 저렇게 WslSdk의 메서드 호출만 추가한 것으로 CoInitializeSecurity가 실패하는 것입니다. 오~~~ 신기하지 않나요? ^^




위의 현상을 간단하게 재현하는 것이 가능합니다. 우선, .NET Framework 콘솔 프로젝트를 생성하고 NativeMethods.CoInitializeSecurity를 호출하는 상태로 만들어 둡니다. 그다음 아래의 소스 코드만 가진 .NET Framework 라이브러리를,

public class Class1
{
    public static void Test() { }
}

콘솔 프로젝트에서 참조 추가해 Test 메서드를 호출하는 코드를 넣어 주면 상황을 재현할 수 있습니다.

using System;

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        var result = NativeMethods.CoInitializeSecurity(
            IntPtr.Zero, (-1), IntPtr.Zero, IntPtr.Zero, NativeMethods.RpcAuthnLevel.None,
            NativeMethods.RpcImpLevel.Impersonate, IntPtr.Zero, NativeMethods.EoAuthnCap.StaticCloaking, IntPtr.Zero);

        Console.WriteLine(result); // 출력 결과: -2147417831

        Class1.Test();
    }
}

만약 저 코드를 JIT 컴파일러가 알지 못하도록 분리시켜 놓으면,

using System;

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        var result = NativeMethods.CoInitializeSecurity(
            IntPtr.Zero, (-1), IntPtr.Zero, IntPtr.Zero, NativeMethods.RpcAuthnLevel.None,
            NativeMethods.RpcImpLevel.Impersonate, IntPtr.Zero, NativeMethods.EoAuthnCap.StaticCloaking, IntPtr.Zero);

        Console.WriteLine(result); // 출력 결과: 0
            
        CallMethod();
    }

    static void CallMethod()
    {
        Class1.Test();
    }
}

이번에는 다시 0이 반환됩니다. 도대체 ^^; 무슨 일이 있는 걸까요?

어쨌든 현상만을 정리해 보면, ^^ JIT 컴파일러는 외부 DLL이 사용되었다는 것만으로 STAThread Main 시작 전에 CoInitializeSecurity를 호출하고 있는 것입니다. 참고로, 해당 현상은 .NET Core 프로젝트에서는 발생하지 않습니다.

(첨부 파일은 이 글의 예제 코드를 포함합니다.)




C# - CoCreateInstance 관련 Inteop 오류 정리
; https://www.sysnet.pe.kr/2/0/12678

Wslhub.Sdk 사용으로 알아보는 CoInitializeSecurity 사용 제약
; https://www.sysnet.pe.kr/2/0/12665

별도 DLL에 포함된 타입을 STAThread Main 메서드에서 사용하는 경우 CoInitializeSecurity 자동 호출
; https://www.sysnet.pe.kr/2/0/12666

COM+ 서버 응용 프로그램을 이용해 CoInitializeSecurity 제약 해결
; https://www.sysnet.pe.kr/2/0/12667

ionescu007/lxss github repo에 공개된 lxssmanager.dll의 CLSID_LxssUserSession/IID_ILxssSession 사용법
; https://www.sysnet.pe.kr/2/0/12676

역공학을 통한 lxssmanager.dll의 ILxssSession 사용법 분석
; https://www.sysnet.pe.kr/2/0/12677

C# - DLL Surrogate를 이용한 Out-of-process COM 개체 제작
; https://www.sysnet.pe.kr/2/0/12668

DLL Surrogate를 이용한 Out-of-process COM 개체에서의 CoInitializeSecurity 문제
; https://www.sysnet.pe.kr/2/0/12670

CoInitializeSecurity의 전역 설정을 재정의하는 CoSetProxyBlanket 함수 사용법
; https://www.sysnet.pe.kr/2/0/12679




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

[연관 글]






[최초 등록일: ]
[최종 수정일: 2/4/2023]

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

비밀번호

댓글 작성자
 




... 16  17  18  19  20  21  22  23  24  25  26  27  28  29  [30]  ...
NoWriterDateCnt.TitleFile(s)
13187정성태12/8/202215290개발 환경 구성: 654. openssl - CA로부터 인증받은 새로운 인증서를 생성하는 방법 (2)
13186정성태12/6/202213066오류 유형: 831. The framework 'Microsoft.AspNetCore.App', version '...' was not found.
13185정성태12/6/202214039개발 환경 구성: 653. Windows 환경에서의 Hello World x64 어셈블리 예제 (NASM 버전)
13184정성태12/5/202212627개발 환경 구성: 652. ml64.exe와 link.exe x64 실행 환경 구성 [1]
13183정성태12/4/202212456오류 유형: 830. MASM + CRT 함수를 사용하는 경우 발생하는 컴파일 오류 정리 [1]
13182정성태12/4/202214254Windows: 217. Windows 환경에서의 Hello World x64 어셈블리 예제 (MASM 버전)
13181정성태12/3/202212775Linux: 54. 리눅스/WSL - hello world 어셈블리 코드 x86/x64 (nasm)
13180정성태12/2/202213563.NET Framework: 2074. C# - 스택 메모리에 대한 여유 공간 확인하는 방법파일 다운로드1
13179정성태12/2/202212294Windows: 216. Windows 11 - 22H2 업데이트 이후 Terminal 대신 cmd 창이 뜨는 경우
13178정성태12/1/202213384Windows: 215. Win32 API 금지된 함수 - IsBadXxxPtr 유의 함수들이 안전하지 않은 이유파일 다운로드1
13177정성태11/30/202213962오류 유형: 829. uwsgi 설치 시 fatal error: Python.h: No such file or directory
13176정성태11/29/202211509오류 유형: 828. gunicorn - ModuleNotFoundError: No module named 'flask'
13175정성태11/29/202215815오류 유형: 827. Python - ImportError: cannot import name 'html5lib' from 'pip._vendor'
13174정성태11/28/202212525.NET Framework: 2073. C# - VMMap처럼 스택 메모리의 reserve/guard/commit 상태 출력파일 다운로드1
13173정성태11/27/202213448.NET Framework: 2072. 닷넷 응용 프로그램의 스레드 스택 크기 변경
13172정성태11/25/202212946.NET Framework: 2071. 닷넷에서 ESP/RSP 레지스터 값을 구하는 방법파일 다운로드1
13171정성태11/25/202212476Windows: 214. 윈도우 - 스레드 스택의 "red zone"
13170정성태11/24/202213357Windows: 213. 윈도우 - 싱글 스레드는 컨텍스트 스위칭이 없을까요?
13169정성태11/23/202214670Windows: 212. 윈도우의 Protected Process (Light) 보안 [1]파일 다운로드2
13168정성태11/22/202212559제니퍼 .NET: 31. 제니퍼 닷넷 적용 사례 (9) - DB 서비스에 부하가 걸렸다?!
13167정성태11/21/202213033.NET Framework: 2070. .NET 7 - Console.ReadKey와 리눅스의 터미널 타입
13166정성태11/20/202212949개발 환경 구성: 651. Windows 사용자 경험으로 WSL 환경에 dotnet 런타임/SDK 설치 방법
13165정성태11/18/202211990개발 환경 구성: 650. Azure - "scm" 프로세스와 엮인 서비스 모음
13164정성태11/18/202213910개발 환경 구성: 649. Azure - 비주얼 스튜디오를 이용한 AppService 원격 디버그 방법
13163정성태11/17/202214239개발 환경 구성: 648. 비주얼 스튜디오에서 안드로이드 기기 인식하는 방법
13162정성태11/15/202215723.NET Framework: 2069. .NET 7 - AOT(ahead-of-time) 컴파일 [1]
... 16  17  18  19  20  21  22  23  24  25  26  27  28  29  [30]  ...