Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting REGDB_E_CLASSNOTREG exception in all platforms except x86 #1522

Open
OmarBazaraa opened this issue Mar 4, 2024 · 5 comments
Open
Labels
bug Something isn't working

Comments

@OmarBazaraa
Copy link

OmarBazaraa commented Mar 4, 2024

Description
I'm trying the "hello world" scenario of consuming a C++/WinRT Runtime Component using a C# console application.
The compilation succeeds and the projection types get generated with no problems, but whenever I run the application, I get the following runtime exception:
System.Runtime.InteropServices.COMException: 'Class not registered (0x80040154 (REGDB_E_CLASSNOTREG))'

I searched online and some references were saying it might be something wrong/incompatible with platforms. That is why I tried a whole bunch of different project configurations, and the only change that worked for me is when I added <PlatformTarget>x86</PlatformTarget> to my C# project. Changing to <PlatformTarget>x64</PlatformTarget> and running the program as x64 didn't work; only x86 works.

I'm new to the whole WinRT and COM world so I have no clue what is going wrong, and I need to be able to run the application on different platforms. Help is really much appreciated!

Version Info
Visual Studio: 17.9.1
Windows SDK: 10.0.22621.0
CppWinRT NuGet: 2.0.220531.1
CsWinRT NuGet: 2.0.7
.NET: 6.0, 7.0, and 8.0 (i.e., I tried on all versions)

Context
Here is how I created the projects...

  1. Created a project using "Windows Runtime Component (C++/WinRT)" template
  2. Implemented the runtimeclass as follows:
// Class.idl
namespace RuntimeComponent1
{
    [default_interface]
    runtimeclass Class
    {
        Class();

        Int32 MyProperty;
    }
}
// Class.h
#pragma once

#include "Class.g.h"

namespace winrt::RuntimeComponent1::implementation
{
    struct Class : ClassT<Class>
    {
        Class() = default;

        int32_t MyProperty();
        void MyProperty(int32_t value);

    private:
        int32_t m_data = 0;
    };
}

namespace winrt::RuntimeComponent1::factory_implementation
{
    struct Class : ClassT<Class, implementation::Class>
    {
    };
}
// Class.cpp
#include "pch.h"
#include "Class.h"
#include "Class.g.cpp"

namespace winrt::RuntimeComponent1::implementation
{
    int32_t Class::MyProperty()
    {
        return m_data;
    }

    void Class::MyProperty(int32_t data)
    {
        m_data = data;
    }
}
  1. Created a C# Console Application
  2. Added CsWinRT NuGet
  3. Added reference to the C++/WinRT Windows Runtime Component project
  4. Updated the csproj to add the following property group:
<PropertyGroup>
    <CsWinRTIncludes>RuntimeComponent1</CsWinRTIncludes>
    <CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
</PropertyGroup>
  1. Updated Program.cs as follows:
using System;

RuntimeComponent1.Class c1 = new ();

c1.MyProperty = 5;

Console.WriteLine(c1.MyProperty);
@OmarBazaraa OmarBazaraa added the bug Something isn't working label Mar 4, 2024
@OmarBazaraa
Copy link
Author

Just tried the C#/WinRT Projection Sample. It works for x64 and gives the same runtime exception when running in x86!

@manodasanW
Copy link
Member

For your local repro, can you confirm a couple things:

  1. You have the DesktopCompatible property set for both x86 and x64.
  2. That the runtime component is being built for x64

With respect to the sample, given building for each architecture requires multiple builds, we only include x64 in the NuGet that is consumed as seen here. That is why you see that x86 errors. Uncommenting out x86 when you do the x86 build should make it pass.

@OmarBazaraa
Copy link
Author

@manodasanW, confirming that...

  1. DesktopCompatible property is set for both x86 and x64 platforms.
  2. The runtime component is being built for x64.

But still the same runtime exception. I just want to clarify that if I removed the <PlatformTarget>x86</PlatformTarget> from the C# application, the application crashes at runtime when running in x86. I don't understand why even though the sample didn't include this PlatformTraget property.

Regarding the sample, I did indeed uncomment the x86 part but it was still not working for me until I removed the project from the solution and re-add it again (strange!). 😅

@OmarBazaraa
Copy link
Author

OmarBazaraa commented Mar 5, 2024

For reference, here are the project files...

RuntimeComponent1.vcxproj:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props')" />
  <PropertyGroup Label="Globals">
    <CppWinRTOptimized>true</CppWinRTOptimized>
    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
    <CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata>
    <MinimalCoreWin>true</MinimalCoreWin>
    <ProjectGuid>{6797a314-3617-4d66-bae5-523705c117d0}</ProjectGuid>
    <ProjectName>RuntimeComponent1</ProjectName>
    <RootNamespace>RuntimeComponent1</RootNamespace>
    <DefaultLanguage>en-US</DefaultLanguage>
    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
    <AppContainerApplication>true</AppContainerApplication>
    <ApplicationType>Windows Store</ApplicationType>
    <ApplicationTypeRevision>10.0</ApplicationTypeRevision>
    <WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.22621.0</WindowsTargetPlatformVersion>
    <WindowsTargetPlatformMinVersion>10.0.22621.0</WindowsTargetPlatformMinVersion>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|ARM">
      <Configuration>Debug</Configuration>
      <Platform>ARM</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|ARM64">
      <Configuration>Debug</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|ARM">
      <Configuration>Release</Configuration>
      <Platform>ARM</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|ARM64">
      <Configuration>Release</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <PlatformToolset>v143</PlatformToolset>
    <PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
    <PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
    <PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
    <GenerateManifest>false</GenerateManifest>
    <DesktopCompatible>true</DesktopCompatible>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
    <UseDebugLibraries>true</UseDebugLibraries>
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
    <UseDebugLibraries>false</UseDebugLibraries>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="Shared">
  </ImportGroup>
  <ImportGroup Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets">
    <Import Project="PropertySheet.props" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <ItemDefinitionGroup>
    <ClCompile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
      <WarningLevel>Level4</WarningLevel>
      <AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
      <!--Temporarily disable cppwinrt heap enforcement to work around xaml compiler generated std::shared_ptr use -->
      <AdditionalOptions Condition="'$(CppWinRTHeapEnforcement)'==''">/DWINRT_NO_MAKE_DETECTION %(AdditionalOptions)</AdditionalOptions>
      <PreprocessorDefinitions>_WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
      <ModuleDefinitionFile>RuntimeComponent1.def</ModuleDefinitionFile>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
    <ClCompile>
      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
    <ClCompile>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClInclude Include="pch.h" />
    <ClInclude Include="Class.h">
      <DependentUpon>Class.idl</DependentUpon>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="pch.cpp">
      <PrecompiledHeader>Create</PrecompiledHeader>
    </ClCompile>
    <ClCompile Include="Class.cpp">
      <DependentUpon>Class.idl</DependentUpon>
    </ClCompile>
    <ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
  </ItemGroup>
  <ItemGroup>
    <Midl Include="Class.idl" />
  </ItemGroup>
  <ItemGroup>
    <None Include="packages.config" />
    <None Include="RuntimeComponent1.def" />
  </ItemGroup>
  <ItemGroup>
    <None Include="PropertySheet.props" />
    <Text Include="readme.txt">
      <DeploymentContent>false</DeploymentContent>
    </Text>
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
    <Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
  </ImportGroup>
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
    <Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
  </Target>
</Project>

ConsoleApp1.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0-windows10.0.22621.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.22621.0</TargetPlatformMinVersion>
    <!-- Set Platform to AnyCPU to allow consumption of the projection assembly from any architecture. -->
    <Platform>AnyCPU</Platform>
    <!-- Workaround for MSB3271 error on processor architecture mismatch -->
    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    <!-- With the following line, the app works only on x86 platform -->
    <!-- Changing this to x64 doesn't make the app work on x64 -->
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\RuntimeComponent1\RuntimeComponent1.vcxproj" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.7" />
  </ItemGroup>

  <!--CsWinRT properties-->
  <PropertyGroup>
    <CsWinRTIncludes>RuntimeComponent1</CsWinRTIncludes>
    <CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
  </PropertyGroup>

</Project>

@OmarBazaraa
Copy link
Author

It turned out that the problem is in <Platform>AnyCPU</Platform>. Changing this to <Platforms>x86;x64</Platforms> fixed the problem for me. I'm not sure what is exactly wrong with using AnyCPU, so it will be nice if you can understand more what is the root cause of the issue and try to solve it in future release of CsWinRT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants