3

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

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

有没有办法解决?

编辑 1

关于下面“Vyacheslav Volkov”的回答,我现在更进一步,谢谢。但是我现在遇到了一个不同的问题。

"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 引用的程序集,则会收到错误消息:

"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, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime'

我正在尝试的完整代码是这样的:

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;

还有什么想法吗?

谢谢,乔恩

编辑 2

最新思路成功解决“{Windows.UI.Xaml, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime}”。

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

然后在“.GetExportedTypes()”中引发异常,即“无法解析对程序集 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 的依赖,因为它没有被预加载。当使用ReflectionOnly API、依赖程序集必须通过 ReflectionOnlyAssemblyResolve 事件进行预加载或按需加载。”。

4

1 回答 1

4

如果您只想发现包含类型,您应该使用Assembly.ReflectionOnlyLoad 方法

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

更新

这是对我有用的代码:

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);
}
于 2013-08-07T13:19:42.093 回答