在Windows 8中的WinRT上动态代码执行(C ++或.NET / C#)?

Windows 8 metro下的WinRT是否允许您动态加载和执行代码? 例如,是否可以将dll下载到内存或隔离存储并从中运行代码? 可以编写JIT编译脚本语言到本地汇编语言(例如第三方浏览器)的代码能够在WinRT中执行相同操作,还是禁止将其作为“不安全”操作?

对于在WinRT中运行的“托管”代码,这个问题的答案是否有所不同? 例如,在托管代码中,您是否可以从Internet下载程序集并使其在MEF中可被发现,或者能够在运行时加载它? 你能用某种forms的Reflection.Emit吗? 在C ++中,您可以运行应用程序在运行时生成的汇编代码,还是在运行时动态加载DLL(可能是某种forms的WinRT DLL)?

你的问题有点不清楚…所以一些一般指示:

  • .NET应用程序使用WinRT(但不是新的UI模型!)
    在这种情况下,今天你可能都有可能(也许不是OLEDB)而是reflection等。

  • 为Metro UI构建的.NET应用程序
    AFAIK这是不可能的(参见http://blogs.microsoft.co.il/blogs/sasha/archive/2011/09/17/metro-net-framework-profile-windows-tailored.aspx和http:// tirania .org / blog / )至少只要你想通过Windows Store销售……在这个范围之外(Windows Store)可能会有一些技巧来规避这种限制,正如一些人已经certificate的那样…但我不会依靠…可能你可以使用一些JavaScript( eval等)来做一些动态但我目前不确定

通常,您无法在Metro风格应用中加载和执行新代码。 您可以访问的是您随应用程序提供的内容。

缺少LoadLibrary和GetProcAddress,因此C ++无法动态加载代码。
同样,C#也不能,因为没有Assembly.Load。
JavaScript可以,但只能在Web容器中,而不是在代码的更全面的信任部分。

所有这一切的原因是,如果应用程序只能加载和运行任意代码,商店的安全/恶意软件保护将没有实际意义。

实际上,Metro风格的应用程序可以动态加载和执行代码。 有一些限制; Metro和Desktop应用程序在关键方面的工作方式略有不同。

机制有所不同,具体取决于调用者(LoadPackagedLibrary()Assembly.Load()等)。 Metro和Desktop之间的一个关键区别 – Metro应用程序只能动态加载应用程序包图(包和s)和系统代码(可以静态加载)中的内容。

有关更多详细信息,请参阅我的posthttp://social.msdn.microsoft.com/Forums/en-US/wingameswithdirectx/thread/d1ebe727-2d10-430e-96af-46964dda8225

Windows 8 metro下的WinRT是否允许您动态加载和执行代码?

没有。

例如,是否可以将dll下载到内存或隔离存储并从中运行代码?

没有。

可以编写JIT编译脚本语言到本地汇编语言(例如第三方浏览器)的代码能够在WinRT中执行相同操作,还是禁止将其作为“不安全”操作?

这将被禁止。

对于在WinRT中运行的“托管”代码,这个问题的答案是否有所不同?

没有。

例如,在托管代码中,您是否可以从Internet下载程序集并使其在MEF中可被发现,或者能够在运行时加载它?

没有。

你能用某种forms的Reflection.Emit吗?

没有。

在C ++中,您可以运行应用程序在运行时生成的汇编代码,还是在运行时动态加载DLL(可能是某种forms的WinRT DLL)?

没有。

您描述的所有内容都可以避免WinRT的安全保障。

为了使它更有趣,IE 10确实在其js代码上执行JIT,因此API显然允许它。

Windows 10为此目的添加了codeGenerationfunction。 这允许在WinRT应用程序中使用VirtualAllocFromApp和VirtualProtectFromApp函数,因为VirtualAlloc和VirtualProtect将在Win32中使用。

您可以创建Windows运行时组件(通用Windows)C ++,从可以调用LoadPackagedLibrary的组件内部的c#代码访问组件,该组件的限制是它只能加载随应用程序打包的DLL。 否则它与LoadLibrary相同。

您无法下载和动态加载,因为ApplicationData和InstalledLocation是不同的位置。 (LoadPackagedLibrary不允许您指定路径)。 而你只能写入ApplicationData …

从AppX包目录(来自MSDN论坛 )加载动态程序集的示例:

 private async Task> GetAssemblyListAsync() { var folder = Windows.ApplicationModel.Package.Current.InstalledLocation; List assemblies = new List(); foreach (StorageFile file in await folder.GetFilesAsync()) { if (file.FileType == ".dll" || file.FileType == ".exe") { var name = file.Name.Substring(0, file.Name.Length - file.FileType.Length); Assembly assembly = Assembly.Load(new AssemblyName() { Name = name }); assemblies.Add(assembly); } } return assemblies; } 

必须将程序集添加到应用程序包中。 您无法从外部源下载它们。

但是, 此方法在.NET Native中不起作用 ,因为所有内容都合并到一个DLL中。 您应该在某处保存一个程序集名称列表(在Assets中的一个简单文件中),并为每个项目调用Assembly.Load

调试模式下的动态程序集列表示例以及发布模式下的预定义程序集名称数组(.NET本机工具链)。

 #if DEBUG using Windows.Storage; #endif // ... IEnumerable assemblyNames; #if DEBUG assemblyNames = Windows.ApplicationModel.Package.Current.InstalledLocation.GetFilesAsync().AsTask().Result .Where(file => file.FileType == ".dll" && file.Name.Contains("Business")) .Select(file => file.Name.Substring(0, file.Name.Length - file.FileType.Length)); #else assemblyNames = new[] { "California.Business", "Colorado.Business" }; #endif foreach (var name in assemblyNames) { var assembly = Assembly.Load(new AssemblyName() { Name = name }); // Load required types. // ... } 

雅可能,检查Windows 8中的谷歌Chrome应用程序,他们提供了一种在正常模式和Windows 8模式之间切换持久查看页面的方法。