성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - Unhandled exception. System.Runtime.InteropServices.COMException (0x800080A5)</h1> <p> 해당 오류를 재현하기 위해, 지난 글에서 실습한 (.NET 8로 만든) C# COM DLL을,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET Core 3/5+ 기반의 COM Server를 기존의 regasm처럼 등록하는 방법 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/13459'>https://www.sysnet.pe.kr/2/0/13459</a> </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System.Runtime.InteropServices; using System; using System.Windows.Forms; namespace ClassLibrary1 { [ComVisible(true)] [Guid("23172f2f-a3d3-4180-97ae-7805f74a5a46")] [InterfaceType(ComInterfaceType.InterfaceIsDual)] public interface IMyNetCode { void ShowDialog(); } [ComVisible(true)] [Guid("41AC8568-9230-4E63-B7C5-CAAD997EE207")] public class MyNetCode : IMyNetCode { public void ShowDialog() { string platform = (IntPtr.Size == 4) ? "x86" : "x64"; MessageBox.Show($" {RuntimeEnvironment.GetSystemVersion()}: {platform}"); } } } </pre> <br /> 동일한 .NET 8 C# Console Application에서 활성화시켜 실행하면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using ClassLibrary1; using System.Runtime.InteropServices; namespace ConsoleApp1 { internal class Program { static void Main(string[] args) { Guid guid = new Guid("{41AC8568-9230-4E63-B7C5-CAAD997EE207}"); Type type = Type.GetTypeFromCLSID(guid); object comObject = Activator.CreateInstance(type); // 예외 발생 } } } </pre> <br /> 이런 오류가 발생합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C:\temp\net45_from_net80\x64\Debug> ConsoleApp1.exe Unhandled exception. System.Runtime.InteropServices.COMException (0x800080A5): Retrieving the COM class factory for component with CLSID {41AC8568-9230-4E63-B7C5-CAAD997EE207} failed due to the following error: 800080a5 0x800080A5. at System.RuntimeTypeHandle.AllocateComObject(Void* pClassFactory) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions) at ConsoleApp1.Program.Main(String[] args) in C:\temp\net45_from_net80\ConsoleApp1\Program.cs:line 16 </pre> <br /> 오류 코드가 0x800080A5 (-2147450715)인데, 검색해도 잘 안 나오는 꽤나 낯선 오류입니다. ^^;<br /> <br /> <hr style='width: 50%' /><br /> <br /> 원인은 프로젝트 설정에서 기인합니다. C# COM DLL 측에서 Windows Forms의 MessageBox.Show를 사용했기 때문에 해당 프로젝트는 다음과 같이 구축한 상태인데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <span style='color: blue; font-weight: bold'><TargetFramework>net8.0-windows</TargetFramework></span> <OutputType>Library</OutputType> <span style='color: blue; font-weight: bold'><UseWindowsForms>true</UseWindowsForms></span> <a target='tab' href='https://www.sysnet.pe.kr/2/0/13459'><EnableComHosting>true</EnableComHosting></a> <a target='tab' href='https://www.sysnet.pe.kr/2/0/13461'><EnableRegFreeCom>true</EnableRegFreeCom></a> <BaseOutputPath>..\x64</BaseOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <Platform>x64</Platform> </PropertyGroup> <PropertyGroup> <SignAssembly>true</SignAssembly> </PropertyGroup> <PropertyGroup> <AssemblyOriginatorKeyFile>test.snk</AssemblyOriginatorKeyFile> </PropertyGroup> <Target Name="PostBuild" AfterTargets="PostBuildEvent"> <Exec Command="<a target='tab' href='https://www.sysnet.pe.kr/2/0/13458'>dscom tlbexport &quot;$(TargetPath)&quot;</a>" /> </Target> <ItemGroup Condition="Exists('$(AssemblyName).tlb')"> <a target='tab' href='https://www.sysnet.pe.kr/2/0/13460'><ComHostTypeLibrary Include="$(AssemblyName).tlb" Id="1"/></a> </ItemGroup> </Project> </pre> <br /> 따라서 호출 측에서도, 비록 Windows Forms 관련 코드를 직접적으로 사용하지 않았지만 마찬가지로 UseWindowsForms 옵션을 추가해야 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <span style='color: blue; font-weight: bold'><TargetFramework>net8.0-windows</TargetFramework></span> <OutputType>Exe</OutputType> <span style='color: blue; font-weight: bold'><UseWindowsForms>true</UseWindowsForms></span> <BaseOutputPath>..\x64</BaseOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <Platform>x64</Platform> <ApplicationManifest>app.manifest</ApplicationManifest> </PropertyGroup> </Project> </pre> <br /> 이후 다시 실행하면, 정상적으로 실행이 됩니다. 그런데, 여기서 재미있는 건, COM Client 역할을 하는 측의 프로젝트를 그냥 일반적인 .NET Framework Console Application으로 만들거나, 단순히 C/C++ 클라이언트로 만든 경우에는 저런 설정과 무관하게 잘 실행이 된다는 점입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 한 가지 더 재미있는 점이 있는데요, COM Server와 클라이언트의 TargetFramework을 아래와 같이 바꾸면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > [C# COM 서버 역할을 하는 ClassLibrary1] <TargetFramework><span style='color: blue; font-weight: bold'>net7.0-windows</span></TargetFramework> <UseWindowsForms>true</UseWindowsForms> [C# COM Client 역할을 하는 ConsoleApp1] <TargetFramework><span style='color: blue; font-weight: bold'>net7.0-windows</span></TargetFramework> <UseWindowsForms>true</UseWindowsForms> </pre> <br /> 당연히 잘 동작하겠지만, RuntimeEnvironment.GetSystemVersion()의 결괏값이 "v4.0.30319"라고 나온다는 점입니다. .NET 8 환경에서는 정상적으로 "v8.0.0"이 나왔던 반면, .NET 7인 경우에는 마치 Desktop용의 .NET Framework을 가리키는 버전이 나오는 것입니다.<br /> <br /> 아울러, 다음과 같이 버전이 서로 일치하지 않는 경우에도,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > [C# COM 서버 역할을 하는 ClassLibrary1] <TargetFramework><span style='color: blue; font-weight: bold'>net7.0-windows</span></TargetFramework> <UseWindowsForms>true</UseWindowsForms> [C# COM Client 역할을 하는 ConsoleApp1] <TargetFramework><span style='color: blue; font-weight: bold'>net8.0-windows</span></TargetFramework> <UseWindowsForms>true</UseWindowsForms> </pre> <br /> 혹은 반대로 하는 경우에도,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > [C# COM 서버 역할을 하는 ClassLibrary1] <TargetFramework><span style='color: blue; font-weight: bold'>net8.0-windows</span></TargetFramework> <UseWindowsForms>true</UseWindowsForms> [C# COM Client 역할을 하는 ConsoleApp1] <TargetFramework><span style='color: blue; font-weight: bold'>net7.0-windows</span></TargetFramework> <UseWindowsForms>true</UseWindowsForms> </pre> <br /> 이유는 알 수 없지만, 동일하게 "0x800080A5" 오류가 발생합니다. (제가 테스트한 것은 .NET 5부터 한 것인데, 모두 COM 서버와 클라이언트의 프로젝트 버전이 동일해야 합니다. 아마도 이전의 .NET Core 런타임에서도 마찬가지 현상이 있을 듯합니다.) 이런 조합의 수까지 고려해 테스트를 하려면, 마이크로소프트도 참 골치 아플 것 같습니다. ^^;<br /><br /> (2023-12-02 업데이트) 정식 문서에 보면,<br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Hosting layer error and exit codes ; <a target='tab' href='https://github.com/dotnet/runtime/blob/main/docs/design/features/host-error-codes.md'>https://github.com/dotnet/runtime/blob/main/docs/design/features/host-error-codes.md</a> </pre> <br /> 0x800080a5에 대해,<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> Error returned by hostfxr_initialize_for_runtime_config if the component being initialized requires framework which is not available or incompatible with the frameworks loaded by the runtime already in the process. For example trying to load a component which requires 3.0 into a process which is already running a 2.0 runtime. </div> <br /> 라는 설명이 나오는군요. ^^ 결국 <a target='tab' href='https://www.sysnet.pe.kr/2/0/13468#800080a5'>지난번의 결론</a>에 해당합니다.<br /> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=2115&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
2123
(왼쪽의 숫자를 입력해야 합니다.)