【问题标题】:Reflecting a WinRT executable from a .Net 4.x App从 .Net 4.x 应用程序反映 WinRT 可执行文件
【发布时间】:2013-08-07 10:29:04
【问题描述】:

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

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 引用有关,并在此处的帖子中进行了说明:Could not load file or assembly '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()”时,“ReflectionOnlyNamespaceResolve”事件只会为命名空间“Windows.UI.Xaml”触发一次,解析为“C:\windows” \system32\WinMetadata\Windows.UI.Xaml.winmd"。

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

【问题讨论】:

  • 你想用这个程序集做什么?
  • 对其进行反思以发现仅用于显示目的的包含类型。我不需要创建任何类型的运行时实例。
  • 仍然得到:“无法加载文件或程序集'System,Version=2.0.5.0,Culture=neutral,PublicKeyToken=7cec85d7bea7798e,Retargetable=Yes'或其依赖项之一。系统找不到指定文件。”
  • 如果您有兴趣,这是针对开源项目“Docu”(github.com/jagregory/docu),允许它读取 Windows 应用商店程序集。我可以 ping 你我正在修改的代码,然后如果我们取得任何进展,我可以更新这个问题。谢谢,乔恩
  • 你解决过这个问题吗?我遇到了类似的问题,发现让 .NET 4.5 应用程序预加载 System.Runtime(在 .NET 4.5 构建的构建过程中添加了 System.Runtime 的引用包含)允许“GetExtractedTypes”成功进行。跨度>

标签: c# reflection windows-store-apps .net-assembly


【解决方案1】:

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

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

【讨论】:

  • 感谢您迄今为止的帮助。这让我更进一步,但仍然没有运气。请查看我修改后的问题...
  • 如果您有兴趣,这是针对开源项目“Docu”(github.com/jagregory/docu),允许它读取 Windows 应用商店程序集。我可以 ping 你我正在修改的代码,然后如果我们取得任何进展,我可以更新这个问题。谢谢,乔恩
  • 仍然得到:“无法加载文件或程序集'System,Version=2.0.5.0,Culture=neutral,PublicKeyToken=7cec85d7bea7798e,Retargetable=Yes'或其依赖项之一。系统找不到指定文件。”
  • 奇怪但对我有用。我编写了从控制台应用程序运行的代码。
  • 我认为这可能是因为我试图反映的 exe 引用了第二个 PCL 库(针对 Profile78),该库与主 exe 位于同一文件夹中。抱歉没有发布这些信息,我想这很相关!在我的代码中,我还必须在与 exe 相同的文件夹中加载 DLL,这在调用 GetExportedTypes 之前很好,这就是我收到有关 System 2.0.5.0 错误的地方...干杯,乔恩
猜你喜欢
  • 2016-01-09
  • 2015-12-01
  • 2015-03-01
  • 1970-01-01
  • 2022-06-29
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
相关资源
最近更新 更多