8

我需要获取一些关于调用我的组件的程序集的元数据。因此,使用Assembly.GetCallingAssembly()似乎是一种天作之合。但是,我发现它在任何地方都可以使用,除了 Windows 应用商店。支持的地方:

但是,不支持它的地方是直接在 Windows 应用商店应用程序中。我可以制作一个可移植的类库,然后在 Windows 应用商店应用程序中从那里调用它,但我不能直接将它放在 Windows 应用商店应用程序/类库中。

是否有这种方法或其他方法来获取由 提供的元数据类型Assembly

4

2 回答 2

7

Assembly.GetCallingAssembly没有在 WinRT 中公开 - 据说是因为它的语义在面对内联等(来源)时不可靠,但它也不太适合 Windows 应用商店应用程序中允许的受限反射。你可以得到类似的东西Assembly.GetCurrentAssembly(),例如:

typeof(MainPage).GetTypeInfo().Assembly

但这根本不一样。使用受限反射模型,也无法像在 .NET 中那样在运行时获取堆栈跟踪。

至于可移植类库,我正要说Assembly.GetCurrentAssembly()一般可移植类库都支持它,但 WinRT 不支持——如果它根本不在那个平台中,这将是有道理的。但实际上,它似乎存在于包括 WinRT 在内的所有配置文件中,除了 WinRT+.NET4.5 - 似乎这里必须有某种疏忽与这种不一致。因此该方法存在于 WinRT 中(而且没有进行重定向),但在编译时可用的元数据中不可见。

因此,您可以使用反射调用该方法:

var assembly = (Assembly) typeof(Assembly).GetTypeInfo()
    .GetDeclaredMethod("GetCallingAssembly")
    .Invoke(null, new object[0]);

我认为这种方法在 Windows 应用商店应用程序中的不可见性是“我们希望这会消失”。

(这个答案只涉及“我可以”而不是“我应该”)。

于 2013-02-07T15:21:42.880 回答
2

该方法被取消只是因为它在 WinRT 应用程序中太不可靠了。WinRT 的一个强有力的设计目标是使不同语言运行时环境之间的互操作变得简单且无故障。效果很好,您可以轻松地以 C# 等语言创建 WinRT 组件,并让以 C++ 或 Javascript 等非托管语言编写的应用程序使用它。

这在桌面 .NET 应用程序中也是可能的,但要复杂得多,必须回退到 [ComVisible] 程序集或使用 C++/CLI 语言创建混合模式程序集。在这种情况下使用 Assembly.GetCallingAssembly() 也会失败,但是程序员完全预计会失败,因为他很清楚要做一些特别的事情。

这在 WinRT 组件中变得更加模糊。特别是因为如果调用实际上是从另一个 .NET 程序集发出的,则它不一定会失败。但是当它来自非托管代码时就没有希望了。

如果没有像样的解决方法,这种随机的失败就是彻底的痛苦。因此,该方法被取消。使用 PCL 是一种可能的解决方法,但微软过去曾严厉警告过,这种黑客形式是非常不推荐的。商店验证程序捕获并导致拒绝的可能性非零。

于 2013-02-07T16:38:26.943 回答