11

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

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

4

9 回答 9

11

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

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

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

于 2011-09-20T03:48:11.093 回答
8

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

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

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

于 2011-12-28T20:51:56.670 回答
7

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

不。

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

不。

JIT 将脚本语言编译为本机汇编语言(例如第三方浏览器)的代码是否能够在 WinRT 中执行相同的操作,或者是否作为“不安全”操作被禁止?

这将被禁止。

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

不。

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

不。

你能以某种形式使用 Reflection.Emit 吗?

不。

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

不。

您描述的所有内容都将允许绕过 WinRT 的安全保证。

于 2011-10-07T16:39:54.700 回答
2

你的问题有点不清楚......所以一些一般性的指针:

  • .NET 应用程序使用 WinRT(但不是新的 UI 模型!)
    在这种情况下,您今天的一切皆有可能(也许不是 OLEDB),但反射等。

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

于 2011-09-19T16:04:39.660 回答
2

Windows 10为此添加了代码生成功能。这允许函数VirtualAllocFromApp和 VirtualProtectFromApp 在 WinRT 应用程序中使用,因为 VirtualAlloc 和 VirtualProtect 将在 Win32 中使用。

于 2015-09-30T05:48:35.890 回答
1

为了让它更有趣,IE 10 实际上在它的 js 代码上做 JIT,所以 API 显然是允许它的。

于 2011-10-10T12:59:38.807 回答
0

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

private async Task<IEnumerable<Assembly>> GetAssemblyListAsync()
{
    var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;

    List<Assembly> assemblies = new List<Assembly>();
    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 中。您应该将程序集名称列表保存在某处(在资产内的一个简单文件中)并Assembly.Load为每个项目调用。

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

#if DEBUG
using Windows.Storage;
#endif

    // ...

    IEnumerable<string> 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.
        // ...

    }
于 2015-12-27T07:56:58.390 回答
0

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

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

于 2015-11-16T06:48:18.720 回答
-1

是的,可能,请检查 Windows 8 中的 Google Chrome 应用程序,它们提供了一种在正常模式和 Windows 8 模式之间切换的方法,以保留查看的页面。

于 2013-01-18T12:31:17.057 回答