Search code examples
c++audiowindows-runtimec++-winrt

Register Windows Runtime Component (c++winrt) in native c++ application


Native c++ application is using c++/winrt classes to instantiate and use winrt::Windows::Media::Audio::AudioGraph.
Inside AudioGraph there is possibility to add effects to graph nodes. There are some already created effects (like echo effect) but there is also possibility to create custom audio effect.
Custom audio effect class must be a Windows Runtime Component. There is a way to create custom audio effect in Windows Runtime Component c++/winrt project by creating class with Windows.Media.Effects.IBasicAudioEffect interface in idl file (and providing implementation). This generates winmd, lib and winrt headers files.
Until this point everything is fine and working. But to instantiate audio effect it need to be registered and this steep I am missing. Application at runtime throw's an exception with "Class not registered" message when I want to instantiate audio effect class and also throw an exception "Failed to activate audio effect" when I want to instantiate it inside AudioGraph node.

I do not know how to registered Windows Runtime Component from native c++ application.

Steps to create and use custom audio effect are describe here https://learn.microsoft.com/en-us/windows/uwp/audio-video-camera/custom-audio-effects. Code is in C# and used in UWP application but it could be converted to c++/winrt almost 1:1.


Solution

  • This article solves this problem:

    https://blogs.windows.com/windowsdeveloper/2019/04/30/enhancing-non-packaged-desktop-apps-using-windows-runtime-components/

    It is possible to use Registration-free WinRT (starting from Windows 10 1903) by modifying application manifest file (and not Windows Runtime Component Package manifest as suggested in documentation) like this:

    <?xml version="1.0" encoding="utf-8"?>
    <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">  
    <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
     
      <file name="WinRTComponent.dll">
        <activatableClass
            name="WinRTComponent.Class1"
            threadingModel="both"
            xmlns="urn:schemas-microsoft-com:winrt.v1" />
        <activatableClass
            name="WinRTComponent.Class2"
            threadingModel="both"
            xmlns="urn:schemas-microsoft-com:winrt.v1" />
      </file>
     
    </assembly>