Reflecting a WinRT executable from a .Net 4.x App

.net-assembly, c#, reflection, windows-store-apps

Solution

If you want only to discover the containing types you should use the Assembly.ReflectionOnlyLoad method.

Assembly.ReflectionOnlyLoadFrom(@"c:\...\MyWinRTApp.exe")

UPDATE

Here's the code that works for me:

AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (sender, eventArgs) => Assembly.ReflectionOnlyLoad(eventArgs.Name);
WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve += (sender, eventArgs) =>
{
    string path =
        WindowsRuntimeMetadata.ResolveNamespace(eventArgs.NamespaceName, Enumerable.Empty<string>())
            .FirstOrDefault();
    if (path == null) return;

    eventArgs.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(path));
};

Assembly loadFrom = Assembly.ReflectionOnlyLoadFrom(@"C:\....\WinRTApp.exe");
Type[] types = loadFrom.GetExportedTypes();
foreach (Type type in types)
{
    Console.WriteLine(type);
}

Problem

In a console application; If I execute: ``` Assembly.LoadFrom(@"c:\...\MyWinRTApp.exe") ``` I get: ``` System.BadImageFormatException occurred HResult=-2147024885 Message=Could not load file or assembly 'file:///C:\_...\MyWinRTApp.exe' or one of its dependencies. An attempt was made to load a program with an incorrect format. Source=mscorlib ``` Is there any way around this? EDIT 1 In relation to "Vyacheslav Volkov"'s answer below, I now get a step further, thank you. However I now get a different issue. ``` "assembly.GetExportedTypes()" now throws "Cannot resolve dependency to Windows Runtime type 'Windows.UI.Xaml.Application'. When using the ReflectionOnly APIs, dependent Windows Runtime assemblies must be resolved on demand through the ReflectionOnlyNamespaceResolve event." ``` If I try to ReflectionOnlyLoad the referenced assemblies, then I get the error: ``` "Could not load file or assembly 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)". ``` This is related to loading winmd references, and explained in the post here: Could not load file or assembly 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime'. The full code I'm trying is this: ``` using System.Runtime.InteropServices.WindowsRuntime; var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath); /*WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve += (x, y) => { y.NamespaceName ??? y.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(???)); return; };*/ foreach (var references in assembly.GetReferencedAssemblies()) { try { Assembly.ReflectionOnlyLoad(references.FullName); } catch (FileNotFoundException) { var fi = new FileInfo(assemblyPath); var fi2Name = String.Format("{0}\\{1}.dll", fi.DirectoryName, references.Name); var fi2 = new FileInfo(fi2Name); if (fi2.Exists) { Assembly.ReflectionOnlyLoadFrom(fi2.FullName); } } catch (FileLoadException) { // When a winmd assembly is attempted. } } return assembly; ``` Any more ideas? Thanks, Jon Edit 2 The latest idea successfully resolves "{Windows.UI.Xaml, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime}". However, when ".GetExportedTypes()" is called on the "Client.exe" assembly, the 'ReflectionOnlyNamespaceResolve' event is only fired once for namespace "Windows.UI.Xaml", which resolves to "C:\windows\system32\WinMetadata\Windows.UI.Xaml.winmd". An exception is then thrown within ".GetExportedTypes()", which is "Cannot resolve dependency to assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.".

Original source

Related problems