Законный backdoor в распространении корпоративных Windows Store приложений
Привет, Хабр! В этой статье мы делимся опытом по распространению корпоративного приложения для Windows Storе.Есть у нас клиент. Отличный клиент, для которого мы создали, внедрили и продолжаем развивать больше портальное решение по дистанционному обслуживанию агентов. Примерно год назад было принято решение о создании мобильного рабочего места сотрудника на базе Windows 8 планшетов.Но создать приложение — это лишь одна задача. Необходимо было продумать следующий шаг: оно должно быть установлено на планшеты компании-заказчика и разойтись по России, потому что конечные пользователи —это представители компании в различных регионах. При этом должен присутствовать механизм обновления приложений, так как без этого, сами понимаете, никуда.На этапе тестирования можно пользоваться приложением в течение одного месяца, установив лицензию разработчика, что мы и делали (ссылка). Но когда-то приходит время запускать приложение в жизнь. Мы рассмотрели различные варианты:
Распространение через магазин приложений.Способ кажется заманчивым: выпускаем приложение, в котором функционал «для своих» защищён паролем, и использовать приложение по назначению смогут только сотрудники. Но такое распространение нарушает правила публикации в магазине приложений. Есть большая вероятность получить в ответ ревью (как это уже бывало с iOS приложениями):2.12 We found that your app is intended for a very limited, or niche, set of users — your company. Использование программ управления компьютерами организации, такими как Windows Intune (ссылка), Air-Watch (ссылка).Это серьёзные решения, требующие дополнительных затрат на их приобретение и настройку; кроме того, их должны взять в обиход IT-службы компании. Использование этих систем, бесспорно, решает практически все проблемы по удалённому управлению и мониторингу устройств, но на текущий момент заказчик не был готов настраивать и использовать эти системы. Как во многих случаях есть свой путь, только надо немного поискать… Установщик обновленийМы решили попробовать справиться с задачей самостоятельно и изобрести велосипед создать программу, которая помогает настраивать OC перед установкой приложения, непосредственно устанавливать и обновлять наше приложение c Modern UI интерфейсом.Дело в том, что корпоративные планшеты, которые используют в компании, были x86 с установленной Windows 8 Professional. Такая архитектура позволяет запускать не только приложения из магазина, но и «старые добрые» программы.Итак, алгоритм казалось бы, стандартен:
Пользователь получает инсталлятор и устанавливает классическую программу-«обновлялку». Программа проверяет доступность новой версии приложения, и если таковая имеется — скачивает готовый пакет. Программа разворачивает пакет и запускает установочный скрипт. И вот приложение установлено/обновлено. Sideloading Но, как водится, не всё так гладко — есть нюансы. Есть ещё одна трудность, которую нам создал Microsoft и которую надо было обходить: на некоторых конфигурациях системы установка приложений вообще заблокирована. Приложения нельзя установить, если в настройках групповой политики не установлено значение «Allow trusted apps to install». При этом сама настройка недоступна для некоторых платформ. Детали механизма sideloading (здесь).Установка приложений доступна, если:
Для операционной системы Windows 8 Enterprise, Windows 8 Professional:
Компьютер должен быть в домене.
В настройках групповой политики установлено значение «Allow trusted apps to install».
Для операционных систем Windows 8 Enterprise, Windows 8 Professional, Windows RT: На компьютере должен быть активирован специальный ключ (sideloading key). Sideloading key — это 25-значный ключ (похож на ключ активации для Windows).
В настройках групповой политики установлено значение «Allow trusted apps to install».
В варианте с добавлением компьютеров в домен нам было отказано, но ключ для активации sideloading предоставили.Как же выглядит установка ключа и настройка политики для пользователя? Может быть, присланная инструкция по установке вместе с ключом решает проблему?
Для начала установите sideloading key. Откройте командную строку от имени администратора и введите команды: slmgr /ipk
После установки программа сворачивается в трэй и сразу же запускает автоматическую проверку обновлений. Если приложение не установлено, в трее появляется вот такое сообщение:
Нажимаем на него, появляется сама форма, на которой есть краткое описание приложения, информационное окно, прогресс-бар и кнопки. В информационном окне могут быть надписи типа: «Доступно обновление…», «Установка приложения…» и т.п.
После установки приложение находится в трее и периодически (несколько раз в сутки) запрашивает сервер на предмет обновлений. Если обновления имеются, приложение оповещает об этом пользователя.
Есть смысл немного заострить внимание на технической реализации некоторых частей программы.
Примеры кода Настройка групповой политики public static void SetGroupPolicy () { var key = Registry.LocalMachine.CreateSubKey (@«Software\Policies\Microsoft\Windows\Appx»); //…проверки… key.SetValue («AllowAllTrustedApps», 1, Microsoft.Win32.RegistryValueKind.DWord); } Установка Sideloading Key public static void InstallSideloadingKey () { // Проверить, установлен или нет sideloading key if (IsSideloadKeyInstalled ()) return; Process p = new Process () { StartInfo = new ProcessStartInfo () { FileName = @«C:\Windows\System32\slmgr.vbs», }, }; // Установить ключ p.StartInfo.Arguments = »/ipk » + _sideloadingKey; p.Start (); p.SuppressPopups (); p.Close ();
// Активировать ключ p.StartInfo.Arguments = »/ato ec67814b-30e6–4a50-bf7b-d55daf729d1e»; p.Start (); p.SuppressPopups (); p.Close (); } Проверка, что ключ установлен private static bool IsSideloadKeyInstalled () { // Проверяем, какие ключи установлены в системе и есть ли среди них // наш sideloading key. bool result = false; Process p = new Process () { StartInfo = new ProcessStartInfo () { FileName = @«C:\Windows\System32\slmgr.vbs», }, };
p.StartInfo.Arguments = »/dlv»;
// Команда выводит список всех ключей в системе в отдельном окне. p.Start ();
for (int i = 0; (i < 10) && (!p.HasExited); i++) { p.Refresh();
if (p.MainWindowHandle.ToInt32() != 0) { var list = WindowsHelper.GetChildWindows (p.MainWindowHandle); foreach (var ptr in list) { string windowText = WindowsHelper.GetText (ptr); if (windowText.Contains («APPXLOB») && windowText.Contains (_sideloadingKeyPart)) { result = true; } }
// Закрываем окно с информацией о ключах WindowsHelper.CloseWindow (p.MainWindowHandle);
Thread.Sleep (1000); } p.Close ();
return result; } Установка пакета приложения public static void UpdateApp (string appxPath) { if (String.IsNullOrEmpty (appxPath)) { // Не найден файл .appxbundle» return; } // // Сформировать команду string command = @»/C powershell Add-AppxPackage »; command += appxPath;
// Обновить приложение или установить с нуля? var package = PackageHelper.GetPackage (); if (package!= null) { // Приложение уже установлено — надо обновлять command += » -Update»; }
Process p = new Process () { StartInfo = new ProcessStartInfo () { WorkingDirectory = @«C:\», FileName = «cmd.exe», Arguments = command, RedirectStandardOutput = true, UseShellExecute = false, }, EnableRaisingEvents = true, };
p.Exited += (s, e) => { // Проверить результат процесса установки var pr = s as Process; string text = pr.StandardOutput.ReadToEnd (); if (String.IsNullOrEmpty (text)) { // Приложение установлено успешно. Уведомить об этом пользователя. else // В процессе установки произошла ошибка. };
p.Start (); // Start process p.WaitForExit (); } Заключение Описанный способ распространения, конечно, весьма запутанный. Есть методы для распространения Windows 8 приложений гораздо более правильные и удобные. Но условия, в которые мы были поставлены, заставили нас решить задачу именно таким образом. При таком решении вам и заказчику не придется покупать и настраивать какие-либо сторонние системы; вы не будете грузить пользователя сложными алгоритмами установки приложения; у вас не будет поводов опасаться, что приложение не пройдёт сертификацию.