反映来自.Net 4.x App的WinRT可执行文件 [英] Reflecting a WinRT executable from a .Net 4.x App

查看:87
本文介绍了反映来自.Net 4.x App的WinRT可执行文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在控制台应用程序中;如果我执行:

In a console application; If I execute:

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

我得到:

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

有什么解决办法吗?

关于下面的维亚切斯拉夫·沃尔科夫的回答,我现在要进一步走,谢谢。但是我现在遇到了另一个问题。

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."

如果我尝试ReflectionOnlyLoad引用的程序集,则会出现错误:

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)".

这与加载winmd引用有关,并在帖子中进行了解释:无法加载文件或程序集'Windows,版本= 255.255.255.255,Culture = neutral,PublicKeyToken = null,ContentType = WindowsRuntime'。

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;

还有其他想法吗?

谢谢, Jon

最新想法成功解决了 {Windows.UI.Xaml,版本= 255.255。 255.255,Culture = neutral,PublicKeyToken = null,ContentType = WindowsRuntime}。

The latest idea successfully resolves "{Windows.UI.Xaml, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime}".

但是,在 Client.exe程序集上调用 .GetExportedTypes()时, ReflectionOnlyNamespaceResolve事件仅针对命名空间 Windows.UI.Xaml触发一次,该事件解析为 C:\windows\system32\WinMetadata\Windows.UI.Xaml.winmd。

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".

然后在 .GetExportedTypes()中引发异常,即无法解析对程序集'System.Runtime,版本= 4.0.0.0,文化=中性,PublicKeyToken = b03f5f7f11d50a3a ',因为尚未进行预加载。在使用ReflectionOnly API时,必须根据需要通过ReflectionOnlyAssemblyResolve事件预加载或加载相关程序集。。

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.".

推荐答案

如果您只想涵盖您应该使用 Assembly.ReflectionOnlyLoad方法

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

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

更新

以下是对我有用的代码:

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);
}

这篇关于反映来自.Net 4.x App的WinRT可执行文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆