CoInitializeSecurity를 제대로 부르고 싶으면 결국은 네이티브의 힘을 빌릴 수 밖에 없는 걸까요?

정말 다양한 이유로 CoInitializeSecurity를 사용해야 할 이유가 있습니다. 저 개인적으로는 WSLAPI.DLL의 함수들을 이용하고 싶기 때문인데, 정말 안타깝게도 이 함수들은 Win32 API이지만 내부적으로 LXSS Manager를 감싼 형태에 불과하기 때문에 CoInitializeSecurity를 잘 불러줘야 합니다.

한참을 찾아보다 결국은 아래 글에서 설명하는 것처럼 닷넷 프레임워크든 닷넷 코어이든 관리 코드를 COM 인터페이스로 등록하고, Native Shim에서 CoInitializeSecurity를 원하는대로 불러준 다음, 해당 COM 인터페이스를 부르도록 하는 것이 가장 현실적인 방안같이 보입니다. (혹은 .NET 런타임 호스팅 API를 대신 부른다던가.)

c# - CoInitializeSecurity for managed application, creating a shim? - Stack Overflow

혹시 이 문제에 대해서 고민해보신 다른 분들의 의견을 구하고 싶습니다.

좋아요 3

(지금 코딩 상황이 아니어서.)

그 q&a글의 원본인 pinvoke를 보면 2개의 의견이 나옵니다. 첫 번째는 managed에서 할수 없다고 단정하지만 두 번째는 STAThread 특성을 미리 지정하지 않으면 된다고 하는데요. 후자의 의견이 맞을 것입니다.

제가 언젠가 clr profiler내에서 테스트했을때도 clr 내부에서는 CoInitialize를 호출하지 않았습니다. 따라서 그걸로 인한 암시적 호출은 없었을 것이고 그것도 호출하지 않으면서 CoInit…Sec… 함수를 호출하진 않았을 것입니다.

혹시 관련한 최소 예제 프로젝트가 있으면 저도 빠르게 테스트 해볼 수 있을 것 같습니다.

좋아요 4

@kevin13 님의 도움을 정말 많이 받고 있습니다. 너무나 감사드립니다.

CoInitializeSecurity가 네이티브 함수이다보니 STAThread 말고 혹시 어디서 딴데서 미리 부르는데가 있지 않나? 하고 무척 고민했는데 정말 거기뿐이라면 정말 다행이네요 =_=

그런데 달리 말하면 PowerShell 기본 환경에서는 정말 COM 서버로 WSL 관련 feature를 export해서 불러오는 것 외에는 방법이 없을지도 모르겠군요. (아니면 wsl.exe의 출력을 활용하던지)

좋아요 2

@kevin13 님의 조언을 토대로 테스트를 좀 더 해봤는데, STAThread나 MTAThread 자체는 닷넷 코어든 닷넷 프레임워크든 CoInitializeSecurity를 부르는 트리거는 아닌 것 같습니다. 콘솔 앱에서는 Main 메서드에 저 어트리뷰트가 어떻게 붙든 상관이 없었고, 지정을 안하면 디폴트는 MTAThread를 붙인 것과 동일한 상태였습니다.

반면 COM에 대한 의존성이 있는 LINQPad나 PowerShell, 그리고 Windows Forms에서도 웹 브라우저 컨트롤을 추가한 후에 CoInitiailizeSecurity를 불러보니 확실히 RPC_E_TOO_LATE가 HRESULT로 반환되었습니다.

좋아요 2

그럼 일단 현실적으로는 문제가 해결되었다는 의미인 거죠? ^^

좋아요 2

제 관점에서는요. 하지만 PowerShell이나 LINQPAD 같은 환경에서는 WSL API를 직접 못쓴다는 이야기는 여전해서 이 부분은 관련해서 이슈가 나올 때마다 known issue로 거론이 되는게 맞지 않나 싶네요.

좋아요 2