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.
I'm going to re-summarize here, based on what I have come to, going through more of the documentation.
When you create a WinUI App, you can create a Packaged app with a packaging project or without. Here was my first mistake. The second project template is still a Packaged App and not an Unpackaged App. So keep that in mind while choosing your approach. The above tutorial says that the tutorial is specific to Unpackaged Apps, but it is applicable to both Packaged and Unpackaged Apps.
The tutorial describes how to consume WinRT Components calling it Registration Free. But WinRT is a Registration Free framework. Calling it Registration Free was misleading. Registration Free simply meant that it uses a manifest and doesn't mean you can gain access to the component without registering it with the App. Unless late binding (calling plugins), you will have to follow the Registration Free in application registration.
When making a Packaged App I needed to include the NuGet package Microsoft.VCRTForwarders.140. The tutorial uses app.manifest to declare activatableClasses. This is a shortcut, and really, you need to use the Package.appxmanifest to acquire full framework functionality; like declaring Proxy-Stub Servers for Interfaces. I use the Propertysheet.props to include the winmds and move the dll's into the exe folder, instead of just making a reference to the winmd and manually copying the dll's.
Here I learned I wasn't actually making an Unpackaged App. To make an Unpackaged App, first I had to make a Packaged App with no packaging project. Then, WindowPackageType had to be set to None and AppxPackage to false in the project file. Package.appxmanifest had to be removed from the project. I no longer needed the NuGet. Instead I needed to install the required framework bits, and load the Bootstrapper. This enabled connectivity and started the winrt framework in the Unpackaged environment. When not late binding, I included the winmds and moved my dll's into the executable folder using the Propertysheet.props. In this way I was able to use winrt get_activation_factory to make Runtime Classes in WinUI Components. There was no single document that covered this.
I found the easiest way to late bind WinRT components was--in an unpackaged or packaged app--was to load the dll using WINRT_IMPL_LoadLibraryW from base.h and call the GetActivationFactory directly using WINRT_IMPL_GetProcAddress. The only problem with this was that the Xaml framework didn't just extend into the WinUI Component. Xaml content was unable to load in the loaded component dll. I believe there is a way to add Xaml functionality, but it looks like it mixes with legacy WRL code and Xaml islands.
My solution to this last problem was to start another WinUI process. I Loaded a sub App from an App as a driver for the code behind. Other than to have a call up application, I don't see why I'd personally use controls defined in WinUI component dll's, and will simply use the main processes to drive behind UI logic in modular WinRT dll's. Especially with my Desktop Application already being so modular. Need new UI functionality, make a new one off of a template. For my purposes this makes the most sense. WinUI, WinRT, and Windows::Foundation all work without Xaml. I even passed a SwapChainPanel to a WinUI Component dll to make late binding DirectX12 graphics pipelines, so we're doing good.
I am using an external manifest for a very simple program I have written, program.exe. I have an external manifest, program.exe.1.manifest, in the same directory. These are the contents:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"
manifestVersion="1.0"
>
<assemblyIdentity
name="TestC.Testos.TestEx"
processorArchitecture="amd64"
type="win32"
version="0.1.0.0"
/>
<description>TestTool</description>
<file
loadFrom="%homepath%\Desktop\source\payload.dll"
name="payload.dll"
/>
</assembly>
Now, the simple program simply calls LoadLibraryW(L"payload.dll"). The payload.dll is located in the Windows directory of the system, however, I am trying to load a version of payload.dll from a folder called source on my desktop. This works when I embed the manifest in the program directly, but does not when it is an external manifest. Why does an external manifest not work?
I am trying to test the newer Geolocation API (in place of the older ILocation COM API), which is a WinRT API.
I 've followed instructions from here to allow a normal C++ desktop Win32 app to call Windows 10 RT functions. It works normally in my tests.
However, for location, I must include a capability in a XML file as discussed here.
How am I supposed to create this XML file? I tried creating a file like this:
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
<Capabilities>
<!-- DeviceCapability elements must follow Capability elements (if present) -->
<DeviceCapability Name="location"/>
</Capabilities>
<Identity Name=""
Version=""
Publisher="" />
<Properties>
<DisplayName></DisplayName>
<PublisherDisplayName></PublisherDisplayName>
<Logo></Logo>
</Properties>
<Prerequisites>
<OSMinVersion></OSMinVersion>
<OSMaxVersionTested></OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="" />
</Resources>
<Applications>
<Application Id="" StartPage="">
<VisualElements DisplayName="" Description=""
Logo="" SmallLogo=""
ForegroundText="" BackgroundColor="">
<SplashScreen Image="" />
</VisualElements>
</Application>
</Applications>
</Package>
I am not sure what to do from now on. Is there a compiler setting that would tell the compiler/linker to include this appxmanifest file?
Thanks
I have a Java application on Windows that's launched through a packr exe. I need to turn off DPI scaling by default. I don't have control of the exe's generation.
My understanding is that I can do this by adding an external .manifest file, but it doesn't seem to work.
This is the manifest file, which I put at "Airships.exe.manifest" next to "Airships.exe".
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="Airships.exe"/>
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings
xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</asmv1:assembly>
Is there something incorrect about this manifest?
Does an external manifest actually work by default, or do I have to embed it into the .exe somehow?
NB this related question doesn't actually have an answer.
I'm trying to implement the MediaPlugin but I am running into a problem. I have done all steps in the setup instructions and get the following error:
Error: No resource found that matches the given name (at 'resource' with value '#xml/file_paths')
As explained in the setup instructions - in my Android project, I have added a folder inside the Resources-folder, called xml - containing a file called file_paths.xml with the following contents:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="Pictures" />
<external-files-path name="my_movies" path="Movies" />
</paths>
I expect this problem to be related to either the above or the AndroidManifest.xml, so I'll include my complete AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.company.Kvitt" android:installLocation="auto">
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application android:label="Kvitt.Android">
<provider android:name="android.support.v4.content.FileProvider"
android:authorities="com.company.Kvitt.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"/>
</provider>
</application>
</manifest>
Any help or ideas on how to solve this error are really appreciated!
The res/xml directory should be in the same sub-folder as other Resources; drawable, layout, mipmap-XXX, etc...
Do a clean all / build all just as a double check
Double-check your xml path in the project: Resources/xml/file_paths.xml
After a build, check the build artifacts for the file in obj/Debug/android/res/xml
If the resource file is not in the build artifacts the likely cause is the build action is wrong
Check that the build action on the file is set to AndroidResource