Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 8개 있습니다.)

별도 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

비밀번호

댓글 작성자
 




... 46  [47]  48  49  50  51  52  53  54  55  56  57  58  59  60  ...
NoWriterDateCnt.TitleFile(s)
12476정성태1/5/202110704.NET Framework: 996. C# - 닷넷 코어에서 다른 스레드의 callstack을 구하는 방법파일 다운로드1
12475정성태1/5/202113289.NET Framework: 995. C# - Span<T>와 Memory<T> [1]파일 다운로드1
12474정성태1/4/202110732.NET Framework: 994. C# - (.NET Core 2.2부터 가능한) 프로세스 내부에서 CLR ETW 이벤트 수신 [1]파일 다운로드1
12473정성태1/4/20219575.NET Framework: 993. .NET 런타임에 따라 달라지는 정적 필드의 초기화 유무 [1]파일 다운로드1
12472정성태1/3/20219864디버깅 기술: 178. windbg - 디버그 시작 시 스크립트 실행
12471정성태1/1/202110357.NET Framework: 992. C# - .NET Core 3.0 이상부터 제공하는 runtimeOptions의 rollForward 옵션 [1]
12470정성태12/30/202010554.NET Framework: 991. .NET 5 응용 프로그램에서 WinRT API 호출 [1]파일 다운로드1
12469정성태12/30/202014108.NET Framework: 990. C# - SendInput Win32 API를 이용한 가상 키보드/마우스 [1]파일 다운로드1
12468정성태12/30/202010686Windows: 186. CMD Shell의 "Defaults"와 "Properties"에서 폰트 정보가 다른 문제 [1]
12467정성태12/29/202010830.NET Framework: 989. HttpContextAccessor를 통해 이해하는 AsyncLocal<T> [1]파일 다운로드1
12466정성태12/29/20208606.NET Framework: 988. C# - 지연 실행이 꼭 필요한 상황이 아니라면 singleton 패턴에서 DCLP보다는 static 초기화를 권장파일 다운로드1
12465정성태12/29/202011803.NET Framework: 987. .NET Profiler - FunctionID와 연관된 ClassID를 구할 수 없는 문제
12464정성태12/29/202010640.NET Framework: 986. pptfont.exe - PPT 파일에 숨겨진 폰트 설정을 일괄 삭제
12463정성태12/29/20209674개발 환경 구성: 520. RDP(mstsc.exe)의 다중 모니터 옵션 /multimon, /span
12462정성태12/27/202011271디버깅 기술: 177. windbg - (ASP.NET 환경에서 유용한) netext 확장
12461정성태12/21/202012061.NET Framework: 985. .NET 코드 리뷰 팁 [3]
12460정성태12/18/20209926기타: 78. 도서 소개 - C#으로 배우는 암호학
12459정성태12/16/202010253Linux: 35. C# - 리눅스 환경에서 클라이언트 소켓의 ephemeral port 재사용파일 다운로드1
12458정성태12/16/20209653오류 유형: 694. C# - Task.Start 메서드 호출 시 "System.InvalidOperationException: 'Start may not be called on a task that has completed.'" 예외 발생 [1]
12457정성태12/15/20209198Windows: 185. C# - Windows 10/2019부터 추가된 SIO_TCP_INFO파일 다운로드1
12456정성태12/15/20209523VS.NET IDE: 156. Visual Studio - "Migrate packages.config to PackageReference"
12455정성태12/15/20209035오류 유형: 693. DLL 로딩 시 0x800704ec - This Program is Blocked by Group Policy
12454정성태12/15/20209657Windows: 184. Windows - AppLocker의 "DLL Rules"를 이용해 임의 경로에 설치한 DLL의 로딩을 막는 방법 [1]
12453정성태12/14/202010618.NET Framework: 984. C# - bool / BOOL / VARIANT_BOOL에 대한 Interop [1]파일 다운로드1
12452정성태12/14/202010865Windows: 183. 설정은 가능하지만 구할 수는 없는 TcpTimedWaitDelay 값
12451정성태12/14/20209999Windows: 182. WMI Namespace를 열거하고, 그 안에 정의된 클래스를 열거하는 방법 [5]
... 46  [47]  48  49  50  51  52  53  54  55  56  57  58  59  60  ...