Visual Studio 2022. Solution with two projects: a WPF C# UI app, and a Universal Windows (UWP) class library in C++. The former makes a reference to the latter. At compile time, I can see that the C# compiler recognizes classes from the library. When I run the UI app, though, the first time C# tries to instantiate an UWP class, I see the following:
System.TypeLoadException: 'Requested Windows Runtime type 'MyLib.MyClass' is not registered.' COMException: Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
Is this about regular COM registration, or something else? UWP libraries don't have a DllRegisterServer
, so you can't call regsvr32
on them. A copy of DLL can be found in the bin\Debug folder where the WPF executable is.
In the debug output, I can see that the winmd file for the library is being loaded, but the library itself isn't.
This is somewhat similar, but that one is about consuming the UWP API from .NET, the system classes, not classes from custom libraries.
EDIT: not specific to WPF. A dummy console .NET Framework project exhibits the same.
Visual Studio 2022. Solution with two projects: a WPF C# UI app, and a Universal Windows (UWP) class library in C++. The former makes a reference to the latter. At compile time, I can see that the C# compiler recognizes classes from the library. When I run the UI app, though, the first time C# tries to instantiate an UWP class, I see the following:
System.TypeLoadException: 'Requested Windows Runtime type 'MyLib.MyClass' is not registered.' COMException: Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
Is this about regular COM registration, or something else? UWP libraries don't have a DllRegisterServer
, so you can't call regsvr32
on them. A copy of DLL can be found in the bin\Debug folder where the WPF executable is.
In the debug output, I can see that the winmd file for the library is being loaded, but the library itself isn't.
This is somewhat similar, but that one is about consuming the UWP API from .NET, the system classes, not classes from custom libraries.
EDIT: not specific to WPF. A dummy console .NET Framework project exhibits the same.
Share Improve this question edited Mar 19 at 12:01 Seva Alekseyev asked Mar 17 at 17:16 Seva AlekseyevSeva Alekseyev 61.5k25 gold badges172 silver badges296 bronze badges 5- You error can be caused by a different version of library installed on machine or the library is wrong type (32 vs 64). – jdweng Commented Mar 17 at 17:37
- x64 on both the app and the lib. – Seva Alekseyev Commented Mar 17 at 17:41
- Did you try registering the dll from SysWow64 folder ? support.microsoft/en-us/topic/… – jdweng Commented Mar 17 at 17:47
- "DLL failed to load" - which is consistent with DLL being 64-bit :) It's not about bitness. UWP libraries are not supposed to be registered. – Seva Alekseyev Commented Mar 17 at 17:57
- 1 Historical footnote. A bit of irony here, assuming if the rumor I heard is correct. Brian Harry so hated COM that he created an experimental VM that allowed programatic access to TFS, just to avoid having to work with COM. Due to a perfect storm of circumstances (involving Microsoft, Sun, Java, JVM, and a legal squabble), that VM seed of an idea became .NET. And had to be made to interop with COM. Bringing things full circle. – Eljay Commented Mar 17 at 18:55
3 Answers
Reset to default 2To be clear here, you're talking about WinRT registration. Once you correctly classify your problem, the answer becomes much easier to find.
In .NET that is usually handled by CsWinRT
, which is a source generator package that takes your WinRT dependencies and it generates the necessary code to create its objects and access their properties. Do note however that WPF and source generators don't mix, you'll have to do this in an external .NET Standard 2.0 library.
Additionally it's important to know that WinRT object files (your .dll) can run in both registered mode (like regular COM objects) and in registration-free mode. The latter is usually preferred, but if you want to register them you definitely can -- I just fet the name of the thing you have to run, it obviously won't work with regsvr32
because it's not a COM class object, it's WinRT.
Your issue is due to the UWP class library not being properly registered. Deploy the UWP project first (Right-click → Deploy), or package the WPF app using MSIX to ensure the UWP component is registered. Let me know if you need setup guidance!
Blindy's mention of the registration free COM was the right clue, but hardly the whole story.
Registration free COM is accomplished by listing dependent classes and the DLLs they live in the app manifest. There are two ways of providing the app manifest - as an embedded resource in the executable, and as a standalone file. The .NET toolchain defaults to the former, but won't let you customize it (that I know of). So under the WPF (.NET) project properties, Application tab, change the Manifest setting to "Create application without a manifest". Instead, create a file in the bin\Debug directory with a name like Myproject.exe.manifest
with the following contents (substitute your own names and versions):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false"/> </requestedPrivileges>
</security>
</trustInfo>
<file name="MyLib.dll">
<activatableClass
name="MyLib.MyClass"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
</assembly>
The top <assemblyIdentity>
/<trustInfo>
elements come from the .NET's toolchain, and they seem to be entirely generic - the toolchain does not even place the proper assembly name there. The <file>
element is the essence of reg free COM - that's how you tell the framework that the component MyLib.MyClass
lives in MyLib.dll
.
Finally, if you want to debug it, you need to provide a copy of the Visual C++/UWP runtime libraries where the .NET app can find them. Navigate to C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs\14.0\Appx\Debug\x64
(the path may vary, and mind the CPU architecture). There, you'll see Microsoft.VCLibs.x64.Debug.14.00.appx
. APPX is a renamed ZIP file. Make a copy, rename to ZIP, and extract the following files into the bin\Debug:
- msvcp140d_app.dll
- vccorlib140d_app.dll
- vcruntime140_1d_app.dll
- vcruntime140d_app.dll
The DLLs that make up the VS runtime (and paths, and versions) are subject to change over time; this answer was correct as of Visual Studio 2022 17.13.3 but might go obsolete.
Building a UWP component library with static RTL is not supported, I've tried.
As an aside note, the word "manifest" is terribly overloaded, even within the Microsoft world.