Home > Blockchain >  WinUI Registration Free WinRT Component
WinUI Registration Free WinRT Component

Time:07-09

I followed the following tutorial on how to register a UWP registration free WinRT component https://blogs.windows.com/windowsdeveloper/2019/04/30/enhancing-non-packaged-desktop-apps-using-windows-runtime-components/ but I continue to receive errors about the component not being registered.

I begin by creating a Propertysheet.props sheet, like in the tutorial:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup />
  <ItemDefinitionGroup />
  <ItemGroup />
    <ItemGroup>
        <Reference Include="C:\Users\User\Solution\x64\Debug\Component\Component.winmd">
            <IsWinmdFile>true</IsWinmdFile>
        </Reference>
        <ReferenceCopyLocationPaths Include="C:\Users\User\Solution\x64\Debug\Component\Component.dll">
            <IsWinmdFile>false</IsWinmdFile>
        </ReferenceCopyLocationPaths>
        <!--<Reference Include="C:\Users\User\Solution\x64\Debug\Component2\Component2.winmd">
            <IsWinmdFile>true</IsWinmdFile>
        </Reference>
        <ReferenceCopyLocationPaths Include="C:\Users\User\Solution\x64\Debug\Component2\Component2.dll">
            <IsWinmdFile>false</IsWinmdFile>
        </ReferenceCopyLocationPaths>-->
    </ItemGroup>
</Project>

When the solution is compiled, the Winmd and the dll for Component are added to the DUALITY.exe folder, but only the Winmd for Component2 has been auto added so I remmed it out for now. I then add the Propertysheet.props to the Application project using the properties manager utility. This disabled the ability to add reference, but it still works as though it has been added. My app.manifest looks 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="Application.app"/>

  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
    </windowsSettings>
  </application>
    
    
  <file name="Component.dll">
    <activatableClass
        name="Component.SubNamespace.Class"
        threadingModel="both"
        xmlns="urn:schemas-microsoft-com:winrt.v1" />
  </file>
  <!--<file name="Component2.dll">
    <activatableClass
        name="Component.PeregrineX12"
        threadingModel="both"
        xmlns="urn:schemas-microsoft-com:winrt.v1" />
  </file>-->
    
</assembly>

There were concerns about Namespace and I itterated through a few possibilities. I get an error in my Appmanifest.xml at line 39:

"DEP0700: Registration of the app failed. [0x80080204] error 0xC00CE012: App manifest validation error: The app manifest must be valid as per schema: Line 39, Column 8, Reason: Content for element '{http://schemas.microsoft.com/appx/manifest/foundation/windows10}InProcessServer' is incomplete according to the DTD/Schema. Expecting: {http://schemas.microsoft.com/appx/manifest/foundation/windows10}ActivatableClass."

and the Appmanifest.xml looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap rescap build" xmlns:build="http://schemas.microsoft.com/developer/appx/2015/build">
  <Identity Name="837f0535-5d07-4290-983b-a49988c57b12" Publisher="CN=User" Version="1.0.0.0" ProcessorArchitecture="x64" />
  <Properties>
    <DisplayName>Application</DisplayName>
    <PublisherDisplayName>User</PublisherDisplayName>
    <Logo>Assets\StoreLogo.png</Logo>
  </Properties>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.22000.0" MaxVersionTested="10.0.22000.0" />
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
    <PackageDependency Name="Microsoft.WindowsAppRuntime.1.1" MinVersion="1001.524.1918.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
    <PackageDependency Name="Microsoft.VCLibs.140.00.Debug" MinVersion="14.0.30704.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
    <PackageDependency Name="Microsoft.VCLibs.140.00.Debug.UWPDesktop" MinVersion="14.0.30704.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
  </Dependencies>
  <Resources>
    <Resource Language="EN-US" />
  </Resources>
  <Applications>
    <Application Id="App" Executable="Application.exe" EntryPoint="Windows.FullTrustApplication">
      <uap:VisualElements DisplayName="Application" Description="DUALITY" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
        <uap:SplashScreen Image="Assets\SplashScreen.png" />
      </uap:VisualElements>
    </Application>
  </Applications>
  <Capabilities>
    <rescap:Capability Name="runFullTrust" />
  </Capabilities>
  <Extensions>
    <Extension Category="windows.activatableClass.inProcessServer">
      <InProcessServer>
        <Path>Component.dll</Path>
      </InProcessServer>
    </Extension>
  </Extensions>
  <build:Metadata>
    <build:Item Name="cl.exe" Version="19.31.31107.0" />
    <build:Item Name="OptimizingToolset" Value="None" />
    <build:Item Name="TargetRuntime" Value="Native" />
    <build:Item Name="Microsoft.UI.Xaml.Markup.Compiler.dll" Version="1.0.0.0" />
    <build:Item Name="Microsoft.UniversalCRT.Debug" Version="10.0.22000.0" />
    <build:Item Name="makepri.exe" Version="10.0.22621.1 (WinBuild.160101.0800)" />
  </build:Metadata>
</Package>

At this point, this was the first time an attempt was made by the framework to register the dll. This is all of the information I have collected from documentation, at this time. As can be seen ActivatableClass was not added and I'm pretty sure it should have been.

CodePudding user response:

When following the tutorial refenced above, when working in WinUI 3.0, to overcome the error that the component is unregistered:

  1. also include the NuGet package Microsoft.VCRTForwarders.140 which does some plumbing. Applying the package to my solution did break one of my projects and I am trying to fix it.

  2. do proceed with Propertysheet.props as described, keeping note to target winmd's from solution/x64 not under merged, and to copy the dll's to the exe directory. add one to every project.

  3. linker automatically includes app.manifest in main project. do not follow this tutorial and use this file to declare activatableClasses. edit your Package.appmanifest to add the dll and the ativatableClass as an in or out of proc server instead. using app.manifest is a shortcut and you only gain full functionality through Package.appmanifest; like adding Interfaces and a ProxyStub. Package.appmanifest declarations are required or the project won't resolve the dll and if the class is called in a translation unit, compilation will fail if the ActivatableClass hasn't been declared. follow the schema https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/appx-package-manifest

  4. the winmd under reference will now be added and replaced every rebuild because of the PropertySheet.props inclusion and the reference to the winmd

  5. Interfaces are not ActivatableClasses and are defined under a ProxyStub Extension in Package.appmanifest

  6. only the Application.exe project should have a Package.appmanifest that describes the Applications dependency structure (seems obvious)

  7. If you are opening Appmanifest.xml using Visual Studio Code, careful, VS Code might not be opening the newest file

  8. there seems to be disconnect between how this is done in UWP vs WinUI however small

I'm trying to late bind using an API component proxy-server to allow the software to instantiate classes handled entirely by their interfaces and class factories with GUID's, or using something classic COM like. I desire to have a WinRT App call an unknown 3rd party component by an identifier given to it in a script or xml project file. From the process I just went through, this does not seem possible without resorting to classic COM. I'm ok with that. The base of the software can be built from components at compile time, while the back end operates in classic COM.

  • Related