Динамическое выполнение кода на WinRT в Windows 8 (C ++ или .NET / C #)? - PullRequest
10 голосов
/ 19 сентября 2011

Позволяет ли WinRT под Windows 8 Metro динамически загружать и выполнять код?Например, возможно ли загрузить dll в память или в изолированное хранилище и запустить код из нее?Может ли код, с помощью которого JIT компилирует язык сценариев на родной язык ассемблера (например, сторонние браузеры), делать то же самое в WinRT, или это запрещено как «небезопасная» операция?

Отличается ли ответ на этот вопрос для «управляемого» кода, работающего в WinRT?Например, в управляемом коде вы могли бы загрузить сборку из Интернета и обнаружить ее в MEF или иным образом загрузить во время выполнения?Можете ли вы использовать Reflection.Emit в какой-либо форме?В C ++, можете ли вы запустить ассемблерный код, сгенерированный приложением во время выполнения, или динамически загрузить DLL во время выполнения (предположительно, некоторую форму WinRT DLL)?

Ответы [ 9 ]

11 голосов
/ 20 сентября 2011

Как правило, вы не можете загружать и выполнять новый код в приложении в стиле Metro. Вы можете получить доступ к тому, что вы отправляете с приложением.

LoadLibrary и GetProcAddress отсутствуют, поэтому C ++ не может динамически загружать код.
Аналогично, C # не может, потому что нет Assembly.Load.
JavaScript может, но только в веб-контейнере, а не в полных довольных частях кода.

Причина для всего этого является то, что безопасность / защита от вредоносных программ магазина будет спорно, если приложение может просто загрузить и запустить произвольный код.

8 голосов
/ 29 декабря 2011

На самом деле, приложения в стиле Metro CAN динамически загружают и выполняют код. Есть некоторые ограничения; Приложения Metro и Desktop работают по-разному в основных направлениях.

Механизмы немного различаются в зависимости от вызывающей стороны (LoadPackagedLibrary () Assembly.Load () и т. Д.). Одно ключевое отличие между Metro и рабочим столом - приложения Metro могут динамически загружать только то, что находится на графике пакетов вашего приложения (ваш пакет и его) и системный код (который в противном случае мог бы быть загружен статически).

Смотрите мой пост для некоторых деталей http://social.msdn.microsoft.com/Forums/en-US/wingameswithdirectx/thread/d1ebe727-2d10-430e-96af-46964dda8225

7 голосов
/ 07 октября 2011

Позволяет ли WinRT под Windows 8 Metro динамически загружать и выполнить код?

Нет.

Например, возможно ли загрузить dll в память или в изолированное хранилище и запустить с нее код?

Нет.

Может ли код, с помощью которого JIT компилирует язык сценариев на родной язык ассемблера (например, сторонние браузеры), делать то же самое в WinRT, или это запрещено как «небезопасная» операция?

Это было бы запрещено.

Отличается ли ответ на этот вопрос для "управляемого" кода, работающего в WinRT?

Нет.

Например, в управляемом коде вы можете загрузить сборку из Интернета и обнаружить ее в MEF или иным образом загрузить во время выполнения?

номер

Можете ли вы использовать Reflection.Emit в какой-либо форме?

номер

В C ++, можете ли вы запустить ассемблерный код, сгенерированный вашим приложением во время выполнения, или динамически загрузить DLL во время выполнения (предположительно, некоторую форму WinRT DLL)?

номер

Все, что вы описали, позволило бы обойти гарантии безопасности WinRT.

1 голос
/ 30 сентября 2015

Windows 10 добавляет для этой цели возможность codeGeneration .Это позволяет использовать функции VirtualAllocFromApp и VirtualProtectFromApp в приложениях WinRT, так как VirtualAlloc и VirtualProtect будут использоваться в Win32.

1 голос
/ 10 октября 2011

Чтобы сделать его более интересным, IE 10 на самом деле выполняет JIT для своего js-кода, поэтому API явно там позволяет это делать.

1 голос
/ 19 сентября 2011

Ваш вопрос немного неясен ... поэтому некоторые общие указатели:

  • .NET-приложение, использующее, среди прочего, WinRT (но НЕ новую модель пользовательского интерфейса!)
    В этом случае возможно все, что вы сегодня (возможно, не OLEDB), но Reflection и т. Д.

  • .NET приложение, созданное для Metro UI
    AFAIK это невозможно (см. http://blogs.microsoft.co.il/blogs/sasha/archive/2011/09/17/metro-net-framework-profile-windows-tailored.aspx и http://tirania.org/blog/) по крайней мере, если вы хотите продавать через Магазин Windows ... за пределами этой области (Магазин Windows) могут быть некоторые хитрости, чтобы обойти это ограничение, как уже продемонстрировали некоторые ... но я бы не рассчитывал на это ... МОЖЕТ, вы можете использовать некоторый JavaScript (eval и т. д.), чтобы сделать что-то динамическое, но я не уверен, в настоящее время

0 голосов
/ 27 декабря 2015

Пример динамической загрузки сборки из каталога пакета 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. Вы должны сохранить список имен сборок где-нибудь (в простом файле внутри Assets) и вызывать 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.
        // ...

    }
0 голосов
/ 16 ноября 2015

Вы можете создать Компонент времени выполнения Windows (универсальный Windows) C ++. Вы получаете доступ к Компоненту из кода c #, внутри компонента вы можете вызвать LoadPackagedLibrary, у которого есть ограничение, что он может загружать только те DLL, которые упакованы с вашим приложением.В противном случае он аналогичен LoadLibrary.

Загрузка и динамическая загрузка невозможны, поскольку ApplicationData и InstalledLocation находятся в разных местах.(LoadPackagedLibrary не позволяет указывать путь).И вы можете писать только в ApplicationData ...

0 голосов
/ 18 января 2013

Возможно, проверьте приложение Google Chrome в Windows 8, они предоставляют способ переключения между обычным режимом и режимом Windows 8, сохраняя просмотренные страницы.

...