-
README
-
Frameworks
-
Dependencies
-
Used By
-
Versions
The Microsoft Advertising Framework for XAML provides APIs to serve banner, video interstitial and native advertisements in apps. After adding this NuGet to your project, add a reference to the Microsoft Advertising SDK for XAML extension (may require reopening project).
This package has no dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Microsoft.Advertising.XAML:
Package | Downloads |
---|---|
Microsoft.Services.Store.SDK
The Microsoft Store Services SDK includes advertising and engagement frameworks. After adding this NuGet to your project, add a reference to the extensions you want, such as «Microsoft Advertising SDK for XAML» or «Microsoft Engagement Framework» (may require reopening project). |
74.6K |
GitHub repositories (3)
Showing the top 3 popular GitHub repositories that depend on Microsoft.Advertising.XAML:
Repository | Stars |
---|---|
Drutol/MALClient Not so small client app for Myanimelist.net — Windows 10 UWP & Android |
305 |
thecodrr/BreadPlayer Bread Player, a free and open source music player powered by UWP and C#/.NET with a sleek and polished design built for, and by, the people seeking a better alternative to Groove and Windows Media Player by Microsoft. |
295 |
aalok05/CodeHub A UWP GitHub Client |
176 |
Автор | Сообщение | ||
---|---|---|---|
|
|||
Заблокирован Статус: Не в сети |
Решил здесь собрать воедино все материалы на данный предмет, и выложить Здесь в сабже, НЕ будет обсуждаться кустарное создание разных инсталяционных «сборок винды» (дистрибов), и т.д. — а будет обсуждаться исключительно, очистка уже установленной ранее на компьютер ОС Windows 10 Обсуждаться будет, исключительно ОС Windows 10 — далее по тексту, «винда» Также, не будут обсуждаться никакие корпоративные компы (в т.ч, сервера), а также серверные ОС 01. Изначальный выбор версии (редакции) ОС Windows 10, которую ставим на комп Здесь, имо — не стОит «кидаться» на что-то выше чем Windows 10 Home (за исключением случаев, когда в ней реально [а не, в ваших фантазиях, и т.п.] не хватает чего-то нужного вам — т.е. грубо говоря если сидишь работаешь за Home, хочешь что-то сделать, а не можешь потому что этого функционала нету в Home) ОС Windows 10 — в отличие от предыдущих версий Windows, построена по принципу и идеологии «Windows as service» (waas) — это означает, что: Посему, если вы не хотите изначально поставить себе на комп бОльший набор доп.барахла, а потом усердно выпиливать ту дополнительную хрень из него которой нету в редакции Home — то ставьте сразу, исключительно Home Скрипты в данном сабже, будут посвящены исключительно Home (хотя и для других редакций, они там в них почистят те же компоненты — но вот компоненты которые есть в тех редакциях но их нету в Home, я лично затрагивать не буду — хотя неплохо бы включить и их, в перечень компонент для скриптов очистки) 02. Понимание пакетов (packages), которые стоЯт у вас в вашей уже установленной Windows 10 1. Understand the different apps included in Windows 10 2. Текущий список имеющихся у вас в винде пакетов — можно посмотреть (выгрузить), с помощью: 2.1. Psexec + DB Browser for SQLite 2.2. AppxDBEditor for Windows 10 (Unprotect Preinstalled System Apps for Removal) (жмем там справа на кнопку “Clone or download”, скачиваем себе скрипт этот) 3. Описания пакетов — какой именно пакет, что именно делает? AppxPackageList.txt ######################################################################################## ######################################################################################## # Windows Advertising # Credential Handler for Microsoft Azure Logon – if u r not develeloper, making apps under Microsoft Azure on ur PC — then remove this # Bing apps: # Hello setup UI: # Chat with robot at microsoft support site — you may remove this # Feedbacks sending to Microsoft — surely remove this # App «Getting started” — «trainer» of how to work in Windows 10 — you may remove this # QuickStart Guide showing the basics of using Narrator Feature-Hyde — «trainer» on how to use Narrator app, from «Special possibilities for disabled ppl» of Windows — you may remove this # «Alternative” component for Skype — you may remove this (if you install Skype later, then everything will work in it) # Sticky-notes app — you may remove this # App for VR-goggles hardware — if u r not using such hardware, you may remove this # Microsoft Office: # List of «ur contacts» — has low functionality, and is useful — you may remove this # «Wallet» of payment service from microsoft, works only in the USA — you may remove this # Regular Maps app in Windows — remove this, coz because there are good apps Yandex.maps, and other normal map apps # Solitaire game — you may remove this # Everything about XBox — remove this, if u do not have/use XBox hardware # Your phone can be used not only by you, but also by your computer. Get instant access to the necessary data on your phone directly from your computer. Quickly reply to text messages, access photos without having to email them to yourself, receive notifications from your phone and manage them on your computer — you can remove this # The «OneConnect» app is the «Paid WiFi» Microsoft app and should be removed. («Paid Wifi & Cellular» app) # Old package, from v1511 ISO — you may remove it # Regular app Groove music — Microsoft closes the service Zune Music — remove this # Regular app Movies and TV — remove this if u do not need this #Tools for programmers: — you may remove this # Duolingo- LearnLanguagesforFree # Modern UI Dialog-App for entering Japanese Characters — you may remove this # App to project the Screen to a Wireless Display — you may remove this # Windows Store app and components — by this, you can update the programs bought in it — but if u do not use Microsoft Store, then you may remove it ### Microsoft Edge browser: ## Voice helper Cortana AND search in Start menu — you may remove this (but then, search in Start menu will be removed too) — for info on how to remove Cortana completely, visit this: Microsoft.Windows.Cortana=0 ## Connect app — this app comes bundled with Windows 10. Connect is a new program in Windows 10. Thanks to the Continuum function, it will allow you to easily connect your phone to your computer without the help of a dock or Miracast adapter. If you are unable or unwilling to use the Connect app, you may uninstall it completely in Windows 10 — you may remove this — for info on how to remove Connect completely, visit this: https://winaero.com/blog/how-to-uninsta … indows-10/ ## Mobile Plans — app for choosing of a cellular tariff plan, works for US residents only — you may remove this — to do this, use some tool like Win 10 Tweaker ### Also, these may be in Windows, too: #========================= ######################################################################################## ### Built-in apps: # With this app, you can view any images, modules, projects, shapes, etc. in 3D format. Very simple application — if u do not need it, you may remove it # Package that adds the ability to print to the printer (2D-printer), from the Microsoft3Dviewer app — if u do not need it, you may remove it # Snip&Sketch — this is convenient app for taking screenshots in Windows — if u do not need it, you may remove it # Windows Alarms&Clock app — alarms may be suitable to wake you at morning, including case when u use Windows on ur notebook — if u do not need it, you may remove it # Standard Calculator app — if u do not need it, you may remove it # Windows Camera app — camera functionality in Windows — if u do not need it, you may remove it # Windows Voice Recorder app — simple tool for voice recording — if u do not need it, you may remove it # Microsoft Photos app — standard OS «viewer» for images — if u do not need it, you may remove it # Paint 3D app — simple graphics editor in OS — if u do not need it, you may remove it # RDP (mstsc) app and functionality — you may remove it, if u do not need to connect from ur PC f.e. to ur work office, by RDP # Some microsoft app for testing network speed — if u do not need it, you may remove it # Good photo editor, this is a separate app — if you do not need it, you may remove it # This is Photoshop Express, this is a separate app — if you do not need it, you may remove it # Microsoft Office: # Microsoft Office: ### Image/video extensions: # The HEIF Image Extensions allows Windows 10 devices to read and write files that use the High Efficiency Image File (HEIF) format. Such files may have an extension .heic or .heif — if u surely do not need this (I am unsure that I am), you may remove it # Play VP9 videos in any video app on your Windows 10 device. VP9 is a popular video codec for streaming over the Internet. These VP9 video extensions are designed to take advantage of the hardware capabilities of modern devices. For devices that do not support VP9 video hardware, software support is provided, but playback capabilities depend on video resolution and device specifications. With these extensions, you can also encode VP8 and VP9 content on devices that do not have a hardware video encoder — if u surely do not need this (I am unsure that I am — if this codec is needed for some video, then I neeed this), you may remove it ### Language packs: # Russian language pack — if u do not need to work in russian language, then you may remove it ########### # User account control or UAC in Windows 10 notifies you when you run programs or perform actions that require administrator rights on the computer (which usually means that the program or action will change system settings or files). This is done in order to protect you from potentially dangerous actions and run software THAT can harm your computer — it is NOT recommended to remove this # This is Start menu of Windows, itself — it is NOT recommended to remove this # This is Lock screen of Windows, itself — it is NOT recommended to remove this # This is Settings (fullscreen window) of Windows, itself — it is NOT recommended to remove this # Microsoft has announced the release of a new version of Windows UI Library for software developers – this framework is tied to a lot of Windows programs — it is NOT recommended to remove this # Menu for hot unplug of video adapters — I do NOT recommended to remove this # Print UI — standard printing dialog in Windows — I do NOT recommended to remove this (even if u have no printers installed) # Some new Microsoft technology, there’s almost no info about it by now — I do NOT recommended to remove this 4. Пакеты (packages) которые появлятся в апдейтах винапдейта, в будущем — и ихние, описания 5. Несколько комментариев по поводу некоторых пакетов винды: 03. Как удалять (излишние) пакеты (packages), которые стоЯт у вас в вашей уже установленной Windows 10 1. Для начала, см. выше раздел 02 (просмотр списка уже установленных в вашей винде пакетов, понимание сути пакетов тех, и т.п.) 2. Подумайте и поймите для себя, какие пакеты лично вам сгодятся, а какие — не пригодятся 3. ВАЖНО! — в списке пакетов в разделе 02, указаны также и пакеты, удалять которые НЕ рекомендуется! — внимательно ознакомьтесь там, с подсписком сиих пакетов там 4. Сформируйте (четкий, и проверенный) список пакетов, которые у вас (лично), пойдут на удаление (за основу, можно взять список пакетов в разделе 02) 5. ВАЖНО! — ВСЕ нижеперечисленные действия (каждый шажок там) — проводить очень внимательно и вдумчиво — контролировать каждое свое действие, внимательно читать то что на экране, и вводимые команды, и т.д.! 6. Теперь задача — в БД-файле StateRepository-Machine.srd, найти нужный пакет (по полю PackageFullName), и если у него там в поле IsInbox стоИт значение 1, то изменить это значение на 0 6.1. Раньше, с этой задачей, отлично справлялся сама та прога “DB Browser for SQLite” – можно было, отлично править ею Однако, начиная с определенного релиза 10-й винды – “так просто” править тот файл, стало невозможно 6.2 Потому, чувак один там (Steve), сделал удобный скрипт, позволяющий-таки редактировать поле IsInbox в том файле БД (краткий смысл скрипта: бэкапим тригеры, вырубаем тригеры, правим файл, восстанавливаем тригеры обратно) 6.3 Идем в эту папку, и открываем в ней блокнотом файл “AppxPackageList.txt” 6.4. Пкм на кнопке Пуск, запускаем Windows Power Shell от имени админа 7. Теперь следующая задача — собсна, провести непосредственное удаление пакетов (которые вы хотите удалить) 8. Закрываем все окна, ребутаем комп 9. Пример удаления пакетов: Пример удаления пакетов ВАЖНО! – ЭТО, НЕ БОЛЕЕ ЧЕМ ПРИМЕР! КОГДА БУДЕТЕ ЧИСТИТЬ СВОЮ ВИНДУ, ВАШ ИНДИВИДУАЛЬНЫЙ СПИСОК, МОЖЕТ БЫТЬ ДРУГИМ! 1. Для начала, я выгрузил полный список пакетов из файла C:ProgramDataMicrosoftWindowsAppRepositoryStateRepository-Machine.srd 2. Две колонки оттудова – PackageFullName, и IsInbox – я, скопировал в Excel 3. В экселе, сортанул таблицу по алфавиту 4. Сверившись с перечнем в данном тексте инструкции (список пакетов в разделе 02), я закоментил (символ # там) в экселе строки тех пакетов которые я НЕ буду удалять 5. У оставшихся пакетов – там где суффикс-“код”, убрал этот суффикс, чтобы осталась “красивая” уникальная подстрока 6. Убрал дубликаты строк 7. Посмотрел, есть ли значения “1” в колонке “IsInbox”? Да, есть. Значит, надо править их на 0, в файле StateRepository-Machine.srd 8. Внес список из экселя, в файл “AppxPackageList.txt” – предварительно (в том же экселе), пристыковав справа везде там суффикс “=0” (как было выше в разделе 03.6) 9. Запустил скрипт AppxDBEditor, нажал там “modify” (“m”) – скрипт проработал, заменив в файле StateRepository-Machine.srd значения в поле “IsInbox” по списку 10. Тот же список из экселя – в том же экселе, подготовил его для следующего этапа: 11. Запустил powershell под правами админа (как это сделать — см. выше раздел 02) 12. Закрыл все окна, ребутнул комп 04. Как (и, что именно), еще чистить в винде? Тут, пока накидаю «общие тезисы»: 1. Противник троганья (и/или, отключения) механизма виртуальной памяти (свопа) винды (Virtual Memory) — вот какой (и как, именно) она его сама себе сделала — такой, и нужен ей (в т.ч., и на ноутбуке) 2. Троганье (и/или, отключение) механизма гибернации (Hibernate), в т.ч. и его файла — тут надо и необходимо понимать, что на гибернацию, завязан также и fast boot ОСи (в т.ч., и на ноутбуке) 3. Противник троганья (и/или, изменения) системных разделов винды на диске — вот какие именно (и как именно) она себе создала при установке на диске — так именно, и нужно ей (разные версии винды, могут делать всйо это — по-разному — ну пусть делают, каждая как надо именно ей) — (в т.ч., и на ноутбуке) 4. Противник троганья (и/или, отключения) механизма «восстановление Windows» (а также контрольных точек в нем, и т.д.) — вот как винда механизм этот сама себе настроила, так и нужно ей (в т.ч., и на ноутбуке) 5. Противник троганья (и/или, отключения) механизма «Windows update» — т.к. механизм сей, он, как минимум, ставит/обновляет технологии нужные для самых разных прог, и т.д. (а кумулятивные апдейты вместо этого самому руками иногда ставить, лично мне вломы) — то же, относится и к ноутбукам, и т.д. (с другой стороны, иногда приходится «лечить» ошибки возникающие в сием недоразвитом механизме) — как максимум, стОит настроить в нем, расписание его (в т.ч., и на ноутбуке) 7. Противник отключения механизма «Action center» («центр действий») — как максимум, стОит настроить его, егойными штатными настройками в его штатном интерфейсе) — (в т.ч., и на ноутбуке) 8. Противник отключения субмеханизма «Maintenance» («обслуживание Windows») механизма «Action center» — как максимум, стОит настроить в нем, расписание его (в т.ч., и на ноутбуке) 9. Субмеханизм «Windows Defender», механизма «Action center» — тут «по вкусу». Лично я, всегда оставляю его как есть (как максимум, настроив его, егойными штатными настройками в его штатном интерфейсе) — т.к. юзаю в плюс к нему, еще и второй антивирь (в т.ч., и на ноутбуке) 10. Субмеханизм «Firewall» («брандмауэр») субмеханизма «Windows Defender» механизма «Action center» — противник отключения его при включенном «Windows Defender» — как максимум, стОит настроить его, егойными штатными настройками в его штатном интерфейсе) — (в т.ч., и на ноутбуке) 11. Механизм «Notification center» («центр уведомлений») — тут «по вкусу». В «Notification center», нету как класс истории прошлых уведомлений (на которых, вы нажали «dismiss») — она там в нем, попросту не ведется (и не ведется нигде в винде — максимум что есть тут, это некоторые уведомления некоторых прог, проги те пишут еще и для Event Viewer вдовесок, и можно посмотреть их там, правда сам Event Viewer и его интерфейс [с «удобством» оного], это уже дико старое кондовое и неудобное мамонтово гуано). Даже при отключенном «Notification center» — остаются сами уведомления (их приход), а также остается focus assist, и настройки в нем. Лично я, отключаю механизм «Notification center» (в т.ч., и на ноутбуке) 12. Противник «очисток реестра Windows» (Registry), и т.п. (кроме случаев, когда адресно надо внести какую-то туда настройку, удалить там какую-то нужную настройку, и т.д.) — (в т.ч., и на ноутбуке) 13. Противник «компрессии системных файлов», и т.д. (часто, это предлагается на нубуках, а также в разных твикерах, и т.п.) 14. Сервисы (sevices). При отключении левых тут, опять же, не стОит трогать те которые нелевые — а вместо «отключения» левого сервиса, зачастую лучше удалить целиком его с системы — если он системный, то выпилить его пакет (package), как это было выше (в т.ч., и на ноутбуке) 15. Драйвера (drivers). (в т.ч., и на ноутбуке) 16. Автозагрузка (startup) — (в т.ч., и на ноутбуке) 17. Temp-папки (в т.ч., файлы скачанного винапдейтом, и т.п.) — (в т.ч., и на ноутбуке) 18. Папка пользовательских загрузок (Downloads) — (в т.ч., и на ноутбуке) 19. Настройка (/отключение) все возможных синхронизаций Windows (в т.ч., и на ноутбуке) А кто тут в пунктах, «сторонник» — тех, считаю «юными хакерами» 05. Исправление ошибок произошедших в Windows Update Относится к случаям, когда очередное обновление гадски не хочет устанавливаться, когда не пашет сам винапдейт, и т.д. Инфа по этому поводу на сайте майков, очень сильно разбросана — попытаюсь скомпоновать ее, здесь (не читайте все возможные статьи в инете, типо «ошибка в винапдейте? — устранение за 5 минут!», и т.п. подобный трэш там) Последний раз редактировалось SilentComputer 22.12.2019 11:57, всего редактировалось 11 раз(а). |
Реклама | |
Партнер |
Alexshanghai |
|
Member Статус: Не в сети |
[quote=»SilentComputer»] разве не достаточно поставить Advanced SystemCare Pro ? |
SilentComputer |
|
Заблокирован Статус: Не в сети |
Я раньше, юзал Uninstall Tool |
John13 |
|
Junior Статус: Не в сети |
Грамотнее чистить дистрибутив а не установленную винду. Я пользуюсь для этого MSMG ToolKit, о которой случайно узнал здесь же, на оверах, в каком то комментарии. |
SilentComputer |
|
Заблокирован Статус: Не в сети |
Ну может теоретически и грамотнее, однако допустим я купил ноутбук, а на нем уже стоИт винда Последний раз редактировалось SilentComputer 21.12.2019 11:16, всего редактировалось 1 раз. |
Godlike66 |
|
Member Статус: Не в сети |
SilentComputer писал(а): (также, не пойму никогда тех, кто отключает винапдейт — т.к. он, как минимум, ставит/обновляет технологии нужные для самых разных прог, и т.д. — то же, относится и к ноутбукам, и т.д. — а кумулятивные апдейты вместо этого самому руками иногда ставить, лично мне вломы) лучшее — враг хорошего SilentComputer писал(а): Здесь, имо — не стОит «кидаться» на что-то выше чем Windows 10 Home (за исключением случаев, когда в ней реально [а не, в ваших фантазиях, и т.п.] не хватает чего-то нужного вам — т.е. грубо говоря если сидишь работаешь за Home, хочешь что-то сделать, а не можешь потому что этого функционала нету в Home) нет опять же… я не буду говорить о возведении в домен, как минимум упомяну политики, отсутствие которых заставляет зачастую силньо напрягаться и гуглить, как то или иное изменить в реестре SilentComputer писал(а): Посему, если вы не хотите изначально поставить себе на комп бОльший набор доп.барахла, а потом усердно выпиливать ту дополнительную хрень из него которой нету в редакции Home — то ставьте сразу, исключительно Home опять же нет, ибо те же политики успешно многое могут отключить SilentComputer писал(а): Вам нахрен не нужны также дома, групповые политики (group policies), и т.п. корпоративные «навороты» — которых нету в Home но которые есть в Pro и выше это конкретно Вам не нужны, а вот многим другим они как раз таки сильно нужны Добавлено спустя 2 минуты 6 секунд: SilentComputer писал(а): 2. Противник троганья (и/или, отключения) механизма гибернации (Hibernate), в т.ч. и его файла — т.к. на гибернацию, завязан также и fast boot (в т.ч., и на ноутбуке) нафиг не нужна гибернация, от которой зачастую больше неудобства и проблем SilentComputer писал(а): 4. Противник троганья (и/или, отключения) механизма «восстановление Windows» (а также контрольных точек в нем, и т.д.) — вот как винда механизм этот сама себе настроила, так и нужно ей (в т.ч., и на ноутбуке) опять же практически никогда не помогала в случае проблем с ОС, а зачастую даже ломала запуск ОС после отката на раннюю точку восстановления Добавлено спустя 26 секунд: SilentComputer писал(а): 5. Противник троганья (и/или, отключения) механизма «Windows update» — т.к. механизм сей, он, как минимум, ставит/обновляет технологии нужные для самых разных прог, и т.д. (а кумулятивные апдейты вместо этого самому руками иногда ставить, лично мне вломы) — то же, относится и к ноутбукам, и т.д. (с другой стороны, иногда приходится «лечить» ошибки возникающие в сием недоразвитом механизме) — как максимум, стОит настроить в нем, расписание его (в т.ч., и на ноутбуке) выше уже говорил про это Последний раз редактировалось Godlike66 21.12.2019 11:21, всего редактировалось 1 раз. |
SilentComputer |
|
Заблокирован Статус: Не в сети |
Godlike66 писал(а): лучшее — враг хорошего А старьйо — враг новых версий используемых прог Godlike66 писал(а): нет опять же… я не буду говорить о возведении в домен Это нужно, в домашних условиях? Godlike66 писал(а): как минимум упомяну политики, отсутствие которых заставляет зачастую силньо напрягаться и гуглить, как то или иное изменить в реестре Зачастую, не всйо можно сделать, и политиками — такшта лезть в реестр только, тогда Godlike66 писал(а): это конкретно Вам не нужны, а вот многим другим они как раз таки сильно нужны Для чего? Godlike66 писал(а): нафиг не нужна гибернация, от которой зачастую больше неудобства и проблем 1. Чтобы не убился, fast boot Godlike66 писал(а): опять же практически никогда не помогала в случае проблем с ОС, а зачастую даже ломала запуск ОС после отката на раннюю точку восстановления Тем не менее, простые случаи сбоев, оно лечит Godlike66 писал(а): экшн центр и ценр уведомлений скрываю или отключаю ибо нафиг не нужно +100500 уведомлений особо не нужных в процессе работы Солидарен по центру уведомлений Последний раз редактировалось SilentComputer 21.12.2019 11:38, всего редактировалось 3 раз(а). |
ivanvatnikov |
|
Member Статус: Не в сети |
Полезная, актуальная тема. |
Godlike66 |
|
Member Статус: Не в сети |
SilentComputer писал(а): А старьйо — враг новых версий используемых прог нет SilentComputer писал(а): Это нужно, в домашних условиях? да SilentComputer писал(а): Для чего? выше сказал |
SilentComputer |
|
Заблокирован Статус: Не в сети |
Godlike66 писал(а): нет У кого «нет», у кого — «да» Godlike66 писал(а): да Нихрена я не уловил, для чего нужен домен в домашних условиях Godlike66 писал(а): выше сказал Юзай тупо реестр — политики же, не стОят того чтобы ради них, городить высшую редакцию винды, с доп.барахлом там в ней P.S. Выше в посте своем, я там дополнил ответы еще |
Igor1966 |
|
Member Статус: Не в сети |
Решил все-таки поиграться… Сделал так, как у Вас написано: SilentComputer писал(а): скачав этот архив, распакуйте его в папку с коротким удобным ее путем, например С:PS Что я не так сделал? PS C:WINDOWSsystem32> cd C:PSpsexec.exe -i -s -d cmd.exe PS C:WINDOWSsystem32> Скрин PS |
SilentComputer |
|
Заблокирован Статус: Не в сети |
Igor1966 писал(а): Что я не так сделал? Не учил командный язык, ты Цитата: cd C:PSpsexec.exe -i -s -d cmd.exe Ты в одну команду, «объединил» и «cd», и запуск самОй проги «psexec» Последний раз редактировалось SilentComputer 21.12.2019 11:57, всего редактировалось 1 раз. |
Igor1966 |
|
Member Статус: Не в сети |
SilentComputer писал(а): Срочно исправляйся! Нельзя жить, с такими «знаниями» охохох… |
Rexcor |
|
Member Статус: Не в сети |
Отлично, спасибо за мануал! Вот что осталось windows.immersivecontrolpanel_10.0.2.1000_neutral_neutral_cw5n1h2txyewy 1 Пустил под нож Windows.CBSPreview=0 SilentComputer писал(а): 1. Противник троганья (и/или, отключения) механизма виртуальной памяти (свопа) винды (Virtual Memory) — вот какой (и как, именно) она его сама себе сделала — такой, и нужен ей (в т.ч., и на ноутбуке) Ну фиг знает, я из секты накопитель поменьше да побыстрее, поэтому никаких свопов и гибернаций SilentComputer писал(а): 3. Противник троганья (и/или, изменения) системных разделов винды на диске — вот какие именно (и как именно) она себе создала при установке на диске — так именно, и нужно ей (разные версии винды, могут делать всйо это — по-разному — ну пусть делают, каждая как надо именно ей) — (в т.ч., и на ноутбуке) Каждая последующая сборка десятки тулит свой собственный раздел Rexcovery, нафига он нежен? SilentComputer писал(а): 4. Противник троганья (и/или, отключения) механизма «восстановление Windows» При наличии Acronis True Image все встроенные востанавливалки точно под нож. Бэкап перед любыми махинациями аля засейвился решает. SilentComputer писал(а): 15. Драйвера (drivers). (в т.ч., и на ноутбуке) Если процессор не переходит в простое дальше C-State C2 то долой драйвер Intel RST, ну или есть без него не переходит, то попробовать установить. SilentComputer писал(а): 5. Противник троганья (и/или, отключения) механизма «Windows update» — т.к. механизм сей, он, как минимум, ставит/обновляет технологии нужные для самых разных прог, и т.д. (а кумулятивные апдейты вместо этого самому руками иногда ставить, лично мне вломы) — то же, относится и к ноутбукам, и т.д. (с другой стороны, иногда приходится «лечить» ошибки возникающие в сием недоразвитом механизме) — как максимум, стОит настроить в нем, расписание его (в т.ч., и на ноутбуке) Расписание подразумевает что я хомяк, у которого всё поминутно расписано на год вперёд, не интересно. Настроил так, чтобы оно проверило и установило обновления только после того как я нажму кнопку проверить обновления. SilentComputer писал(а): Psexec + DB Browser for SQLite Я так и не понял зачем этот шаг. Мне хватило дампа из AppxDBEditor |
SilentComputer |
|
Заблокирован Статус: Не в сети |
Rexcor писал(а): Ну фиг знает, я из секты накопитель поменьше да побыстрее, поэтому никаких свопов и гибернаций У мя на нубуке, вообще ssd 32 гиг Rexcor писал(а): Каждая последующая сборка десятки тулит свой собственный раздел Rexcovery, нафига он нежен? Он нужен, под механизм «Восстановление виндовс» (а механизм сей — нужный, имо) Rexcor писал(а): При наличии Acronis True Image все встроенные востанавливалки точно под нож. Бэкап перед любыми махинациями аля засейвился решает. Я давно с ним не работал, не помню уже алгоритмику работы его — можно ли сделать так, чтобы было удобно? Rexcor писал(а): Расписание подразумевает что я хомяк, у которого всё поминутно расписано на год вперёд, не интересно. Настроил так, чтобы оно проверило и установило обновления только после того как я нажму кнопку проверить обновления. Если по расписанию, то умная машина всйо делает за тебя, и не надо кнопку «проверить обновления» жать Rexcor писал(а): Ещё вопросец. DB Browser for SQLite — это удобный просмотрщик той БД — там всйо в виде таблицы на экране, и фильтры, и все 33 удобства — а также, там можно жмакнуть ctrl+a, и скопировать всю таблицу ту, в excel скажем |
Prod |
|
Member Статус: Не в сети |
Не могу обойти данную тему стороной, если кто хочет можете попробовать на виртуалке комплексный твик реестра для отключения телеметрии. |
SilentComputer |
|
Заблокирован Статус: Не в сети |
Prod, всйо это, здОрово конечно — но если не Home, то на корпоративных компах стоящих в офисе предприятия, вряд ли стОит заморачиваться очистками ихних винд… |
Rexcor |
|
Member Статус: Не в сети |
SilentComputer писал(а): то винда всйо равно «втихую» оставит себе некоторый объем под своп, и всйо равно буит свопать С какой-то там сборки помимо hyberfil.sys и pagefile.sys ещё какоё-то swapfile.sys или ещё что-то такое появлялось, прихлопнул тоже. В общем, ключи в реестре DisablePagingExecutive и LargeSystemCache убивают желание венды что либо свопить на диск. Если файл всёж создать, то венда максимум туда в простое запихает редко используемое содержимое оперативки. То есть, больше, чем количество занятой оперативки в простое своп не нужен. Ну может создам такой если Optane за 5 евро на 16 гигов куплю, как раз ещё один M.2 слот пустует. SilentComputer писал(а): А если нубук засыпАть не смогет Традиционный сон более чем решает проблему. SilentComputer писал(а): Плюс, он работает «на лету» — ненадежно Я виндовый софт не использую, только загрузочную флэшку. 2 гига сделал на втором SSD раздел скрытый, туда скопировал содержимое этой флэшки и это теперь замена виндовому рекавери. Бэкаплю, востанавливаю и ковыряюсь в разделах как в десятке, так и в убунте что живёт на том втором ssd. SilentComputer писал(а): А бэкапы — лично я, бэкапирую лишь исключительно мои пользовательские данные Свои данные держу на отдельных разделах, операционкам оставляю прожиточный минимум в виде одно раздела, если ОСь схлопнулась то данные не страдают и так меньше размеры файлов бэкапа операционки. SilentComputer писал(а): Если по расписанию, то умная машина всйо делает за тебя, Венда своим куриным мозгом не может подключиться к спутниковому интернету без помощи действий со стороны пользователя, хотя убунта и ведроид могут. Ну это косяк организации венды, где даже микрософтовские обновлялки не прописываются во встроенный планировщик. |
SilentComputer |
|
||
Заблокирован Статус: Не в сети |
Rexcor писал(а): С какой-то там сборки помимо hyberfil.sys и pagefile.sys ещё какоё-то swapfile.sys или ещё что-то такое появлялось, прихлопнул тоже. В общем, ключи в реестре DisablePagingExecutive и LargeSystemCache убивают желание венды что либо свопить на диск. Если файл всёж создать, то венда максимум туда в простое запихает редко используемое содержимое оперативки. То есть, больше, чем количество занятой оперативки в простое своп не нужен. Ну может создам такой если Optane за 5 евро на 16 гигов куплю, как раз ещё один M.2 слот пустует. Где-то была статья хорошая, почему отключение свопа в винде, делает не лучше а только хуже Rexcor писал(а): Традиционный сон более чем решает проблему. Сон ведь на механизме гибернейта, работает — не будет гибернейта, не будет и сна — не? Rexcor писал(а): Я виндовый софт не использую, только загрузочную флэшку. 2 гига сделал на втором SSD раздел скрытый, туда скопировал содержимое этой флэшки и это теперь замена виндовому рекавери. Бэкаплю, востанавливаю и ковыряюсь в разделах как в десятке, так и в убунте что живёт на том втором ssd. Я тоже раньше так делал, раздел такой загрузочный Rexcor писал(а): Свои данные держу на отдельных разделах, операционкам оставляю прожиточный минимум в виде одно раздела, если ОСь схлопнулась то данные не страдают и так меньше размеры файлов бэкапа операционки. Ох нет, руками я разделы не ваяю, уже давно тож Rexcor писал(а): Венда своим куриным мозгом не может подключиться к спутниковому интернету без помощи действий со стороны пользователя, хотя убунта и ведроид могут. Ну это косяк организации венды, где даже микрософтовские обновлялки не прописываются во встроенный планировщик. Убунта сейчас, вродеж есть в 10-ке, как подсистема вызываемая? — сделай подключение к спутнику, из-под убунты встроенной как-то Добавлено спустя 4 часа 45 минут 3 секунды: Можно конечно, положить своп на отдельный физический iRam-диск и чтобы при загрузке компа, он сначало заполнялся с какого-то пзу-носителя, а потом собсна уже грузилась сама винда — например, при включении компа, сначало грузится какая-то оболочка которая заполняет ирам, а потом она ребутает комп и передает загрузчик на в10 — грузится в10, видит сразу свой любимый диск со своим любимым свопом, и не ругается А можно, хранить своп, на отдельном SSD-диске что я лично собсна и делаю, т.к. у меня винда (со своим свопом, и всеми своими причиндалами) на «чисто системном» ssd (которого, мне «нежалко»), а вся моя юзердата и т.п. на другом ssd Добавлено спустя 18 минут 34 секунды:
|
XIMERA123 |
|
Member Статус: Не в сети |
Godlike66 писал(а): Солидарен по центру уведомлений так нафиг они сдались? любой вирус его отрубает в первую очередь и дефендер становится инвалидом. |
—
Кто сейчас на конференции |
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6 |
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения |
Лаборатория
Новости
Здравствуйте, товарищи! Прошло чуть больше полугода после выхода предыдущей статьи о Windows 10 Sophia Script — скрипте, который за прошедшие годы стал самым крупным (а их осталось всего два) опенсорс-проектом по персонализации и настройке Windows 10, а также автоматизации рутинных задач. В статье я расскажу, что изменилось с момента релиза версии, описываемой в статье от 29.09.2020, с какими трудностями мы столкнулись, и куда всё движется.
Как всё начиналось
Разработка наброска скрипта берёт своё начало в те далёкие времена, когда после года работы экономистом в отделе проектирования птицефабрики в одной организации я решил перейти в местный отдел IT.
Перейдя на новое место, я предложил автоматизировать настройку пользовательских ОС. Так, через пару недель, появился первый прародитель данного модуля — примитивный .reg-файл для настройки Windows 8.1. Но я и ему был рад, так как всё было в новинку.
Так продолжалось, наверное, год, пока я не понял, что упёрся в тупик и надо менять язык: начал готовить «батник».
В первый день выхода Windows 10 я сразу же «пересел» на неё, поняв, что Windows 8.1 осталась для Microsoft в прошлом. Со временем же «батник» рос, «мужал», разрастался и в какой-то момент даже стал дёргать другой интерпретатор, powershell.exe. Скорость работы падала, и я понимал, что придётся учить PowerShell, так как batch уже не удовлетворяет моим маниакальным запросам автоматизировать всё при настройке ОС.
Как сейчас помню, в феврале 2017 года я сел читать первую статью по запросу «как внести данные в реестр с помощью PowerShell». Уже к лету 2017 года я значительно продвинулся в переписывании всех имеющих функций из «батника» в новый скрипт.
Изначально, конечно, скрипт состоял лишь из одного файла с расширением .ps1. Пользователям приходилось править код и комментировать целые функции, чтобы настроить под себя. То ещё удовольствие было…
Помню, как первый раз почувствовал, что я делаю что-то полезное, когда некто создал issue с просьбой указывать, что я исправляю, когда перезаписываю файлы на GitHub. Пришлось вести журнал изменений.
В таком неспешном темпе разработка шла до августа 2019 года, когда я решил поделиться своими наработками здесь. Хотя я читаю Хабр с года эдак 2007-го, зарегистрировался лишь в 2016-м.
Немного облагородил код (ага, 10 раз), добавил описания на английском языке и накатал крохотную статью о своей pet-разработке. Удивительно, но статью пропустили, она попала в бездну, и я сел ждать.
Как сейчас помню: сижу на сеансе в кинотеатре, и приходит уведомление на почту о новом комментарии к моей статье. Так, стоп! Её одобрили?!
Я не успевал отвечать на комментарии! Это была какая-то эйфория. Какой там фильм?! — меня на Хабр пригласили прямым инвайтом! Фурор! Даже код не обо…ли (а там был кровавый мрак) и вообще любезно приняли.
Самым неожиданным поворотом стало то, что через 5 дней после публикации мне написал некий Дмитрий (@oz-zo), прочитавший моё сетование на то, что у меня не хватает знаний, чтобы сделать графическую версию скрипта, даже хотя бы на Windows.Forms. Я был приятно удивлён, что есть ещё один старый безумец. Как выяснилось, старый, но не бесполезный!
Познакомившись, мы запланировали всё сделать примерно за 3 месяца на Windows.Forms, но наше приключение затянулось… больше чем на 1,5 года: лишь в этом месяце мы вышли на финишную прямую по созданию графической версии моего скрипта — SophiApp. Но это уже другая история, и, когда будет что показать, я обязательно расскажу, что мы пережили за время разработки, поделившись нашими инфернальными набросками и наработками.
С того времени как я познакомился с Дмитрием, разработка пошла быстрее: он внёс огромный вклад в создание новых функций, которых не было ни у кого: все графические функции с использованием WPF и логику к ним написал именно он; я лишь объяснил, как получать данные.
Немаловажным событием стало также знакомство с Дэвидом из Канады, который решил сделать самостоятельно
графическую надстройку для Sophia Script
, Sophia Script Wrapper, для повышения удобства редактирования пресет-файла. В текущем варианте пользователь импортирует пресет-файл скрипта, и в программе расставляются радиокнопки в зависимости от закомментированных и раскомментированных функций. Дальше можно настроить под себя и запустить выполнение настроенного пресет-файла.
Хотя Дэвиду уже нормально так, программировать он сел лишь недавно, окончив курсы. Но его программа выполняет ту задачу, для которой её и написали. Одним словом, люди пользуются.
Что поменялось в скрипте
За время, прошедшее с момента выхода прошлой статьи в сентябре, много воды утекло. Скрипт уже и не узнать. Больше 12 000 строк кода… Самые интересные изыскания пришлись на удаление UWP-приложений и закрепление ярлыков на начальный экран.
Напомню, какие версии Windows 10 поддерживает скрипт на данный момент.
Версия |
Маркетинговое название |
Билд |
Архитектура |
Издания |
21H1 |
May 2021 Update |
19043 |
x64 |
Home/Pro/Enterprise |
20H2 |
October 2020 Update |
19042 |
x64 |
Home/Pro/Enterprise |
2004 |
May 2020 Update |
19041 |
x64 |
Home/Pro/Enterprise |
1809 |
LTSC Enterprise 2019 |
17763 |
x64 |
Enterprise |
А теперь пройдёмся по всем доработанным и новым функциям.
Функции касающиеся манипуляций с UWP-приложениями
Наверное, вы уже заметили, что список стал локализованным. Также хочется добавить, что список генерируется динамически, загружая лишь установленные пакеты UWP-приложений в соответствии с текущей локализацией. Как это реализовано?
Свойство DisplayName, которое содержит локализованное имя пакета, находится лишь в одном классе (Get-AppxPackage вам никак тут не поможет, к сожалению):
«Windows.Management.Deployment.PackageManager»
[Windows.Management.Deployment.PackageManager, Windows.Web, ContentType = WindowsRuntime]::new().FindPackages() | Select-Object -Property DisplayName -ExpandProperty Id | Select-Object -Property Name, DisplayName
На выходе вы получите что-то вроде этого (простыню кода прячу под спойлер)
Name DisplayName
---- -----------
1527c705-839a-4832-9118-54d4Bd6a0c89
c5e2524a-ea46-4f67-841f-6a9465d9d515 Проводник
E2A4F912-2574-4A75-9BB0-0D023378592B Сопоставитель приложений
F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE Диалоговое окно "Добавить рекомендованные папки"
Microsoft.AAD.BrokerPlugin Учетная запись компании или учебного заведения
Microsoft.AccountsControl Электронная почта и учетные записи
Microsoft.AsyncTextService AsyncTextService
Microsoft.BioEnrollment Настройка Windows Hello
Microsoft.CredDialogHost Диалоговое окно учетных данных
Microsoft.ECApp Управление глазами
Microsoft.LockApp Экран блокировки Windows по умолчанию
Microsoft.MicrosoftEdgeDevToolsClient Клиент средств разработчика для Microsoft Edge
Microsoft.MicrosoftEdge
Microsoft.Win32WebViewHost Веб-средство просмотра классических приложений
Microsoft.Windows.Apprep.ChxApp SmartScreen Защитника Windows
Microsoft.Windows.AssignedAccessLockApp Приложение "Блокировка" при ограниченном доступе
Microsoft.Windows.CallingShellApp Видеозвонки
Microsoft.Windows.CapturePicker CapturePicker
Microsoft.Windows.CloudExperienceHost Ваша учетная запись
Microsoft.Windows.ContentDeliveryManager Содержимое, предоставленное корпорацией Майкрософт
Microsoft.Windows.NarratorQuickStart Экранный диктор
Microsoft.Windows.OOBENetworkCaptivePortal Поток портала авторизации
Microsoft.Windows.OOBENetworkConnectionFlow Последовательность действий при сетевом подключении
Microsoft.Windows.ParentalControls Функции семьи учетных записей Майкрософт
Microsoft.Windows.PeopleExperienceHost Windows Shell Experience
Microsoft.Windows.PinningConfirmationDialog PinningConfirmationDialog
Microsoft.Windows.Search Windows Search
Microsoft.Windows.SecHealthUI Безопасность Windows
Microsoft.Windows.SecureAssessmentBrowser Тестирование
Microsoft.Windows.ShellExperienceHost Windows Shell Experience
Microsoft.Windows.StartMenuExperienceHost Запустить
Microsoft.Windows.XGpuEjectDialog Безопасное извлечение устройства
Microsoft.XboxGameCallableUI Xbox Game UI
MicrosoftWindows.Client.CBS Windows Feature Experience Pack
MicrosoftWindows.UndockedDevKit UDK Package
NcsiUwpApp NcsiUwpApp
Windows.CBSPreview Предварительный просмотр штрихкодов Windows
windows.immersivecontrolpanel Параметры
Windows.PrintDialog PrintDialog
Microsoft.Services.Store.Engagement Microsoft Engagement Framework
Microsoft.Services.Store.Engagement Microsoft Engagement Framework
Microsoft.UI.Xaml.2.0 Microsoft.UI.Xaml.2.0
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.Advertising.Xaml Microsoft Advertising SDK for XAML
Microsoft.NET.Native.Framework.2.2 Microsoft .Net Native Framework Package 2.2
Microsoft.NET.Native.Framework.2.2 Microsoft .Net Native Framework Package 2.2
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.NET.Native.Runtime.2.2 Microsoft .Net Native Runtime Package 2.2
Microsoft.NET.Native.Runtime.2.2 Microsoft .Net Native Runtime Package 2.2
Microsoft.VCLibs.140.00.UWPDesktop Microsoft Visual C++ 2015 UWP Desktop Runtime Package
Microsoft.VCLibs.140.00.UWPDesktop Microsoft Visual C++ 2015 UWP Desktop Runtime Package
Microsoft.UI.Xaml.2.1 Microsoft.UI.Xaml.2.1
Microsoft.UI.Xaml.2.1 Microsoft.UI.Xaml.2.1
Microsoft.UI.Xaml.2.0 Microsoft.UI.Xaml.2.0
Microsoft.UI.Xaml.2.3 Microsoft.UI.Xaml.2.3
Microsoft.UI.Xaml.2.3 Microsoft.UI.Xaml.2.3
Microsoft.UI.Xaml.2.4 Microsoft.UI.Xaml.2.4
Microsoft.UI.Xaml.2.4 Microsoft.UI.Xaml.2.4
Microsoft.ScreenSketch Набросок на фрагменте экрана
Microsoft.NET.Native.Framework.1.7 Microsoft .Net Native Framework Package 1.7
Microsoft.NET.Native.Framework.1.7 Microsoft .Net Native Framework Package 1.7
Microsoft.NET.Native.Runtime.1.7 Microsoft .Net Native Runtime Package 1.7
Microsoft.NET.Native.Runtime.1.7 Microsoft .Net Native Runtime Package 1.7
Microsoft.VCLibs.120.00 Microsoft Visual C++ Runtime Package
Microsoft.VCLibs.120.00 Microsoft Visual C++ Runtime Package
Microsoft.VCLibs.140.00.UWPDesktop Microsoft Visual C++ 2015 UWP Desktop Runtime Package
Microsoft.VCLibs.140.00.UWPDesktop Microsoft Visual C++ 2015 UWP Desktop Runtime Package
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.WebpImageExtension Расширения для изображений Webp
Microsoft.DesktopAppInstaller Установщик приложения
Microsoft.NET.Native.Framework.2.2 Microsoft .Net Native Framework Package 2.2
Microsoft.NET.Native.Framework.2.2 Microsoft .Net Native Framework Package 2.2
AppUp.IntelGraphicsExperience Центр управления графикой Intel
Microsoft.Windows.StartMenuExperienceHost Запустить
Microsoft.Windows.ShellExperienceHost Windows Shell Experience
Microsoft.Windows.AssignedAccessLockApp Приложение "Блокировка" при ограниченном доступе
Microsoft.WindowsTerminal Windows Terminal
Microsoft.AV1VideoExtension AV1 Video Extension
Microsoft.HEIFImageExtension Расширения для изображений HEIF
Microsoft.Windows.Photos Фотографии (Майкрософт)
Microsoft.UI.Xaml.2.5 Microsoft.UI.Xaml.2.5
Microsoft.UI.Xaml.2.5 Microsoft.UI.Xaml.2.5
Microsoft.WindowsStore Microsoft Store
Microsoft.StorePurchaseApp Узел для покупок в Store
Microsoft.LanguageExperiencePackru-RU Пакет локализованного интерфейса на русском
Microsoft.MicrosoftEdge Microsoft Edge
Microsoft.VP9VideoExtensions Расширения для VP9-видео
MicrosoftWindows.Client.WebExperience Windows Web Experience Pack
Microsoft.WebMediaExtensions Расширения для интернет-мультимедиа
Microsoft.HEVCVideoExtension Расширения для видео HEVC от производителя устройства
MicrosoftWindows.Client.CBS Windows Feature Experience Pack
Microsoft.MicrosoftEdge.Stable Microsoft Edge
Хоть на картинке и не видно, но кнопка «Для всех пользователей» была тоже полностью переписана. Раньше она совершенно неправильно работала. Сейчас же её логика приведена к должному функционалу. По умолчанию при загрузке формы отображается список приложений для текущего пользователя (все системные пакеты и Microsoft Store исключены из списка, так что удалить хоть что-то важное не получится никак, в отличие, кстати, от всех других скриптов в Интернете). При нажатии на кнопку «Для всех пользователей» происходит динамическая перегенерация списка с учётом установленных пакетов во всех учётных записях. То есть вы можете удалить все приложения для текущего пользователя, и форма отобразится пустой, но при запуске функции с ключом «-ForAllUsers» отобразится список пакетов для всех учётных записей.
Как-то меня попросили добавить поддержку PowerShell 7. И всё это было бы смешно, когда бы не было так грустно…
Во-первых, ни для кого не будет секретом, что, хотя в PowerShell 7 исправили очень много багов, в нынешнем виде очень далёк от финальной версии, ведь там до сих пор даже не работает командлет Get-ComputerRestorePoint из коробки. И (в качестве временного решения) Microsoft предложил загружать в сессию недостающие модули из папки PowerShell 5.1, используя аргумент -UseWindowsPowerShell.
Таким образом, мне приходится загружать модули Microsoft.PowerShell.Management, PackageManagement, Appx, чтобы воссоздать работоспособность скрипта на PowerShell 7:
Import-Module -Name Microsoft.PowerShell.Management, PackageManagement, Appx -UseWindowsPowerShell
Во-вторых, код для получения локализованных имен UWP-пакетов не работает в PowerShell 7 вообще, так как Microsoft решил не включать библиотеки WinRT в релизы PowerShell 7, но вынес разработку на отдельные ресурсы: WinRT и Windows.SDK. Это упомянул и Steven Lee в обсуждении на GitHub, а также уведомил, что команда PowerShell решила не включать в дальнейшем в релизы эти библиотеки. Поэтому, чтобы вызвать необходимые API, мне приходится хранить в папке две библиотеки по 26 МБ и 284 КБ. Тут остаётся лишь поставить мем с пингвином.
Код для получения локализованных имен UWP-пакетов на PowerShell 7 выглядит так:
Add-Type -AssemblyName "$PSScriptRootLibrariesWinRT.Runtime.dll"
Add-Type -AssemblyName "$PSScriptRootLibrariesMicrosoft.Windows.SDK.NET.dll"
$AppxPackages = Get-AppxPackage -PackageTypeFilter Bundle -AllUsers
$PackagesIds = [Windows.Management.Deployment.PackageManager]::new().FindPackages().AdditionalTypeData[[Collections.IEnumerable].TypeHandle] | Select-Object -Property DisplayName -ExpandProperty Id | Select-Object -Property Name, DisplayName
foreach ($AppxPackage in $AppxPackages)
{
$PackageId = $PackagesIds | Where-Object -FilterScript {$_.Name -eq $AppxPackage.Name}
if (-not $PackageId)
{
continue
}
[PSCustomObject]@{
Name = $AppxPackage.Name
PackageFullName = $AppxPackage.PackageFullName
DisplayName = $PackageId.DisplayName
}
}
На выходе будет что-то вроде:
Name PackageFullName DisplayName
---- --------------- -----------
RealtekSemiconductorCorp.RealtekAudioControl RealtekSemiconductorCorp.RealtekAudioControl_1.1.137.0_neutral_~_dt26b99r8h8gj Realtek Audio Control
Microsoft.MicrosoftStickyNotes Microsoft.MicrosoftStickyNotes_3.7.142.0_neutral_~_8wekyb3d8bbwe Microsoft Sticky Notes
Microsoft.ScreenSketch Microsoft.ScreenSketch_2020.814.2355.0_neutral_~_8wekyb3d8bbwe Набросок на фрагменте экрана
Microsoft.WindowsCalculator Microsoft.WindowsCalculator_2020.2008.2.0_neutral_~_8wekyb3d8bbwe Windows Calculator
AppUp.IntelGraphicsExperience AppUp.IntelGraphicsExperience_1.100.3282.0_neutral_~_8j3eq9eme6ctt Центр управления графикой Intel
Microsoft.MicrosoftSolitaireCollection Microsoft.MicrosoftSolitaireCollection_4.7.10142.0_neutral_~_8wekyb3d8bbwe Microsoft Solitaire Collection
Microsoft.DesktopAppInstaller Microsoft.DesktopAppInstaller_2020.1112.20.0_neutral_~_8wekyb3d8bbwe Установщик приложения
Microsoft.WindowsStore Microsoft.WindowsStore_12101.1001.1413.0_neutral_~_8wekyb3d8bbwe Microsoft Store
Microsoft.Windows.Photos Microsoft.Windows.Photos_2020.20120.4004.0_neutral_~_8wekyb3d8bbwe Фотографии (Майкрософт)
Microsoft.WebMediaExtensions Microsoft.WebMediaExtensions_1.0.40471.0_neutral_~_8wekyb3d8bbwe Расширения для интернет-мультим…
Microsoft.WindowsCamera Microsoft.WindowsCamera_2021.105.10.0_neutral_~_8wekyb3d8bbwe Камера Windows
Microsoft.StorePurchaseApp Microsoft.StorePurchaseApp_12103.1001.813.0_neutral_~_8wekyb3d8bbwe Узел для покупок в Store
Microsoft.WindowsTerminal Microsoft.WindowsTerminal_2021.413.2245.0_neutral_~_8wekyb3d8bbwe Windows Terminal
Microsoft.WindowsTerminalPreview Microsoft.WindowsTerminalPreview_2021.413.2303.0_neutral_~_8wekyb3d8bbwe Windows Terminal Preview
Аналогичный подход используется для функции восстановления UWP-приложений. Чтобы восстановить пакет, как известно, необходимо вычленить путь до его манифеста.
Код для получения общего списка всех манифестов выглядит так (можете даже выполнить, если, конечно, не удалили все UWP-приложения):
$Bundles = (Get-AppXPackage -PackageTypeFilter Framework -AllUsers).PackageFullName
Get-ChildItem -Path "HKLM:SOFTWAREClassesLocal SettingsSoftwareMicrosoftWindowsCurrentVersionAppModelPackageRepositoryPackages" | ForEach-Object -Process {
Get-ItemProperty -Path $_.PSPath
} | Where-Object -FilterScript {$_.Path -match "Program Files"} | Where-Object -FilterScript {$_.PSChildName -notin $Bundles} | Where-Object -FilterScript {$_.Path -match "x64"} | ForEach-Object -Process {"$($_.Path)AppxManifest.xml"}
И вы увидите что-то вроде:
C:Program FilesWindowsAppsA025C540.Yandex.Music_4.40.7713.0_x64__vfvw9svesycw6AppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.549981C3F5F10_2.2103.17603.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.BingNews_1.0.6.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.BingWeather_1.0.6.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.DesktopAppInstaller_1.11.10771.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.GamingApp_1.0.1.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.GetHelp_10.2102.40951.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Getstarted_10.2.40751.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.HEIFImageExtension_1.0.40978.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.MicrosoftOfficeHub_18.2008.12711.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.MicrosoftSolitaireCollection_4.9.4072.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.MicrosoftStickyNotes_1.8.15.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Paint_10.2103.1.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.People_10.1909.12456.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.PowerAutomateDesktop_1.0.31.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.ScreenSketch_11.2103.13.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.SkypeApp_14.53.77.0_x64__kzf8qxf38zg5cAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.StorePurchaseApp_12103.1001.8.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Todos_0.41.4902.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.VP9VideoExtensions_1.0.40631.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WebMediaExtensions_1.0.40831.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WebpImageExtension_1.0.32731.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Windows.Photos_2021.21030.17018.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsAlarms_1.0.38.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsCamera_2020.503.58.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsmicrosoft.windowscommunicationsapps_16005.13426.20688.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsFeedbackHub_1.2009.10531.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsMaps_1.0.27.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsNotepad_10.2103.6.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsSoundRecorder_1.0.42.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsStore_12103.1001.11.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsTerminal_1.6.10571.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Xbox.TCUI_1.23.28002.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.XboxGameOverlay_1.54.4001.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.XboxGamingOverlay_5.621.4072.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.XboxIdentityProvider_12.67.21001.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.XboxSpeechToTextOverlay_1.21.13002.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.YourPhone_1.21022.202.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.ZuneMusic_10.21012.10511.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.ZuneVideo_10.21021.10311.0_x64__8wekyb3d8bbweAppxManifest.xml
PS C:Windowssystem32WindowsPowerShellv1.0>
Но нам надо сопоставить имя пакета, его локализованное имя в системе и путь до манифеста. Искать будем среди пакетов, которые имеют статус «Staged», то есть готовы к восстановлению.
# Тут нельзя напрямую вписать -PackageTypeFilter Bundle, так как иначе не выдается нужное свойство InstallLocation. Только сравнивать с $Bundles
$Bundles = (Get-AppXPackage -PackageTypeFilter Bundle -AllUsers).Name
$AppxPackages = Get-AppxPackage -AllUsers | Where-Object -FilterScript {$_.PackageUserInformation -match "Staged"} | Where-Object -FilterScript {$_.Name -in $Bundles}
$PackagesIds = [Windows.Management.Deployment.PackageManager, Windows.Web, ContentType = WindowsRuntime]::new().FindPackages() | Select-Object -Property DisplayName -ExpandProperty Id | Select-Object -Property Name, DisplayName
foreach ($AppxPackage in $AppxPackages)
{
$PackageId = $PackagesIds | Where-Object -FilterScript {$_.Name -eq $AppxPackage.Name}
if (-not $PackageId)
{
continue
}
[PSCustomObject]@{
Name = $AppxPackage.Name
PackageFullName = $AppxPackage.PackageFullName
DisplayName = $PackageId.DisplayName
AppxManifest = "$($AppxPackage.InstallLocation)AppxManifest.xml"
}
}
Ну, а дальше уже дело техники. Кстати, если вам надо восстановить все возможные пакеты без разбора, то в этом вам поможет.
# Re-register all UWP apps
$Bundles = (Get-AppXPackage -PackageTypeFilter Framework -AllUsers).PackageFullName
Get-ChildItem -Path "HKLM:SOFTWAREClassesLocal SettingsSoftwareMicrosoftWindowsCurrentVersionAppModelPackageRepositoryPackages" | ForEach-Object -Process {
Get-ItemProperty -Path $_.PSPath
} | Where-Object -FilterScript {$_.Path -match "Program Files"} | Where-Object -FilterScript {$_.PSChildName -notin $Bundles} | Where-Object -FilterScript {$_.Path -match "x64"} | ForEach-Object -Process {"$($_.Path)AppxManifest.xml"} | Add-AppxPackage -Register -ForceApplicationShutdown -ForceUpdateFromAnyVersion -DisableDevelopmentMode -Verbose
# Check for UWP apps updates
Get-CimInstance -Namespace "Rootcimv2mdmdmmap" -ClassName "MDM_EnterpriseModernAppManagement_AppManagement01" | Invoke-CimMethod -MethodName UpdateScanMethod
Мы специально не хотели хардкодить список приложений как на удаление, так и на восстановление, так это слишком топорно. Одним словом, получить локализованные имена приложений реально. Дмитрий создал форму на WPF и накатал логику. Не знаю, почему, но мне с Дмитрием потребовалась, наверное, пара недель, учтя все возможные и невозможные условия использования, заставить всё работать как надо.
Точно таким же способом можно выводить список локализованных имён компонентов Windows и дополнительных компонентов.
Работает экстремально медленно, но спасает то, что у меня выводится лишь захардоженный список компонентов, которые можно безболезненно отключить (и включить опять, конечно).
Get-WindowsOptionalFeature -Online | ForEach-Object -Process {Get-WindowsOptionalFeature -FeatureName $_.FeatureName -Online} | Select-Object -Property FeatureName, DisplayName | Format-Table -AutoSize
Интернационализация скрипта
На необходимость этой фичи обратил внимание @FrankSinatra в комментариях. Интернационализация позволяет избавиться от страшной конструкции вида
if ($RU)
{
}
else
{
}
Отныне в корне папки скрипта находятся папки с названием кода локализации: например, ru-RU, en-US и так далее, где внутри находится файл локализации вида UnsupportedOSBitness = The script supports Windows 10 x64 only. Получить значение локализации можно командой $PSUICulture.
Соответственно, чтобы это всё заработало, мы импортируем указанные локализационные файлы, сохраняя строки в переменную так, чтобы можно было вызывать их в скрипте:
# Sophia.psd1
ConvertFrom-StringData -StringData @'
UnsupportedOSBitness = The script supports Windows 10 x64 only
'@
# Sophia.ps1
Import-LocalizedData -BindingVariable Global:Localization -FileName Sophia
$Localization.UnsupportedOSBitness
И в зависимости от текущей локализации системы скрипт сам будет искать нужный файл. И код чище, и людя́м приятнее! Ну, а если необходимой локализации нет, то по умолчанию загружается английская.
На сегодня скрипт локализован на 8 языков: английский, китайский, немецкий, французский, итальянский, русский, украинский, турецкий, испанский и португальский. В будущем всё-таки планирую разместить языковые файлы на Crowdin, но немного душит жаба платить столько денег за некоммерческий продукт.
Закрепление ярлыков на начальном экране
Используется при этом чистый PowerShell. Изначально я использовал стороннюю программу syspin, но возникло желание всё-таки избавиться от неё. Как вы знаете, с выходом Windows 10 October 2018 Microsoft без шума закрыл доступ к API открепления (закрепления) ярлыков от начального экрана и панели задач: отныне это можно сделать лишь вручную.
Ниже приведён пример кода для закрепления (открепления) ярлыка на начальный экран, который когда-то работал. Как можете видеть, в коде используется метод получения локализованной строки, и для этого нам необходимо знать код строки, чтобы вызвать соответствующий пункт контекстного меню. В данном примере, чтобы закрепить ярлык командной строки, мы вызываем строку с кодом 51201, «Закрепить на начальном экране», из библиотеки %SystemRoot%system32shell32.dll.
Получить список всех локализованных строк удобнее всего через стороннюю утилиту ResourcesExtract.
Попытка закрепить ярлык командной строки устаревшим методом:
# Extract a localized string from shell32.dll
$Signature = @{
Namespace = "WinAPI"
Name = "GetStr"
Language = "CSharp"
MemberDefinition = @"
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
public static string GetString(uint strId)
{
IntPtr intPtr = GetModuleHandle("shell32.dll");
StringBuilder sb = new StringBuilder(255);
LoadString(intPtr, strId, sb, sb.Capacity);
return sb.ToString();
}
"@
}
if (-not ("WinAPI.GetStr" -as [type]))
{
Add-Type @Signature -Using System.Text
}
# Pin to Start: 51201
# Unpin from Start: 51394
$LocalizedString = [WinAPI.GetStr]::GetString(51201)
# Trying to pin the Command Prompt shortcut to Start
$Target = Get-Item -Path "$env:APPDATAMicrosoftWindowsStart MenuProgramsSystem ToolsCommand Prompt.lnk"
$Shell = New-Object -ComObject Shell.Application
$Folder = $Shell.NameSpace($Target.DirectoryName)
$file = $Folder.ParseName($Target.Name)
$Verb = $File.Verbs() | Where-Object -FilterScript {$_.Name -eq $LocalizedString}
$Verb.DoIt()
Сейчас консоль вываливается с ошибкой Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED).)
Хотя, как можно заметить, API, конечно, отдаёт глагол контекстного меню «Закрепить на начальном &экране», но не может его выполнить.
Мы знаем, что текущий макет начального экрана можно выгрузить в формате XML. Но, даже если его настроить должным образом, импортировать макет в профиль текущего пользователя не получится: Import-StartLayout -LayoutPath D:Layout.xml импортирует макеты начального экрана и панели задач только для новых пользователей.
Идея заключается в том, чтобы использовать политику «Макет начального экрана» (Prevent users from customizing their Start Screen), отвечающую за подгрузку предзаготовленного макета в формате XML из определённого места. Таким образом, наш хак будет состоять из следующих пунктов:
-
Выгружаем текущий макет начального экрана.
-
Парсим XML, добавляя необходимые нам ярлыки (ссылки должны вести на реально существующие ярлыки), и сохраняем.
-
С помощью политики временно выключаем возможность редактировать макет начального экрана.
-
Перезапускаем меню «Пуск».
-
Программно открываем меню «Пуск», чтобы в реестре сохранился его макет.
-
Выключаем политику, чтобы можно было редактировать макет начального экрана.
-
И открываем меню «Пуск» опять.
Вуаля! В данном примере мы настроили начальный экран на лету, закрепив на него три ярлыка для текущего пользователя: панель управления, устройства и принтеры и PowerShell, причём без перезапуска или выхода из учётной записи.
<#
.SYNOPSIS
Configure the Start tiles
.PARAMETER ControlPanel
Pin the "Control Panel" shortcut to Start
.PARAMETER DevicesPrinters
Pin the "Devices & Printers" shortcut to Start
.PARAMETER PowerShell
Pin the "Windows PowerShell" shortcut to Start
.PARAMETER UnpinAll
Unpin all the Start tiles
.EXAMPLE
.Pin.ps1 -Tiles ControlPanel, DevicesPrinters, PowerShell
.EXAMPLE
.Pin.ps1 -UnpinAll
.EXAMPLE
.Pin.ps1 -UnpinAll -Tiles ControlPanel, DevicesPrinters, PowerShell
.EXAMPLE
.Pin.ps1 -UnpinAll -Tiles ControlPanel
.EXAMPLE
.Pin.ps1 -Tiles ControlPanel -UnpinAll
.LINK
https://github.com/farag2/Windows-10-Sophia-Script
.NOTES
Separate arguments with comma
Current user
#>
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $false,
Position = 0
)]
[switch]
$UnpinAll,
[Parameter(
Mandatory = $false,
Position = 1
)]
[ValidateSet("ControlPanel", "DevicesPrinters", "PowerShell")]
[string[]]
$Tiles,
[string]
$StartLayout = "$PSScriptRootStartLayout.xml"
)
begin
{
# Unpin all the Start tiles
if ($UnpinAll)
{
Export-StartLayout -Path $StartLayout -UseDesktopApplicationID
[xml]$XML = Get-Content -Path $StartLayout -Encoding UTF8 -Force
$Groups = $XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.Group
foreach ($Group in $Groups)
{
# Removing all groups inside XML
$Group.ParentNode.RemoveChild($Group) | Out-Null
}
$XML.Save($StartLayout)
}
}
process
{
# Extract strings from shell32.dll using its' number
$Signature = @{
Namespace = "WinAPI"
Name = "GetStr"
Language = "CSharp"
MemberDefinition = @"
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
public static string GetString(uint strId)
{
IntPtr intPtr = GetModuleHandle("shell32.dll");
StringBuilder sb = new StringBuilder(255);
LoadString(intPtr, strId, sb, sb.Capacity);
return sb.ToString();
}
"@
}
if (-not ("WinAPI.GetStr" -as [type]))
{
Add-Type @Signature -Using System.Text
}
# Extract the localized "Devices and Printers" string from shell32.dll
$DevicesPrinters = [WinAPI.GetStr]::GetString(30493)
# We need to get the AppID because it's auto generated
$Script:DevicesPrintersAppID = (Get-StartApps | Where-Object -FilterScript {$_.Name -eq $DevicesPrinters}).AppID
$Parameters = @(
# Control Panel hash table
@{
# Special name for Control Panel
Name = "ControlPanel"
Size = "2x2"
Column = 0
Row = 0
AppID = "Microsoft.Windows.ControlPanel"
},
# "Devices & Printers" hash table
@{
# Special name for "Devices & Printers"
Name = "DevicesPrinters"
Size = "2x2"
Column = 2
Row = 0
AppID = $Script:DevicesPrintersAppID
},
# Windows PowerShell hash table
@{
# Special name for Windows PowerShell
Name = "PowerShell"
Size = "2x2"
Column = 4
Row = 0
AppID = "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}WindowsPowerShellv1.0powershell.exe"
}
)
# Valid columns to place tiles in
$ValidColumns = @(0, 2, 4)
[string]$StartLayoutNS = "http://schemas.microsoft.com/Start/2014/StartLayout"
# Add pre-configured hastable to XML
function Add-Tile
{
param
(
[string]
$Size,
[int]
$Column,
[int]
$Row,
[string]
$AppID
)
[string]$elementName = "start:DesktopApplicationTile"
[Xml.XmlElement]$Table = $xml.CreateElement($elementName, $StartLayoutNS)
$Table.SetAttribute("Size", $Size)
$Table.SetAttribute("Column", $Column)
$Table.SetAttribute("Row", $Row)
$Table.SetAttribute("DesktopApplicationID", $AppID)
$Table
}
if (-not (Test-Path -Path $StartLayout))
{
# Export the current Start layout
Export-StartLayout -Path $StartLayout -UseDesktopApplicationID
}
[xml]$XML = Get-Content -Path $StartLayout -Encoding UTF8 -Force
foreach ($Tile in $Tiles)
{
switch ($Tile)
{
ControlPanel
{
$ControlPanel = [WinAPI.GetStr]::GetString(12712)
Write-Verbose -Message ("The `"{0}`" shortcut is being pinned to Start" -f $ControlPanel) -Verbose
}
DevicesPrinters
{
$DevicesPrinters = [WinAPI.GetStr]::GetString(30493)
Write-Verbose -Message ("The `"{0}`" shortcut is being pinned to Start" -f $DevicesPrinters) -Verbose
# Create the old-style "Devices and Printers" shortcut in the Start menu
$Shell = New-Object -ComObject Wscript.Shell
$Shortcut = $Shell.CreateShortcut("$env:APPDATAMicrosoftWindowsStart menuProgramsSystem Tools$DevicesPrinters.lnk")
$Shortcut.TargetPath = "control"
$Shortcut.Arguments = "printers"
$Shortcut.IconLocation = "$env:SystemRootsystem32DeviceCenter.dll"
$Shortcut.Save()
Start-Sleep -Seconds 3
}
PowerShell
{
Write-Verbose -Message ("The `"{0}`" shortcut is being pinned to Start" -f "Windows PowerShell") -Verbose
}
}
$Parameter = $Parameters | Where-Object -FilterScript {$_.Name -eq $Tile}
$Group = $XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.Group | Where-Object -FilterScript {$_.Name -eq "Sophia Script"}
# If the "Sophia Script" group exists in Start
if ($Group)
{
$DesktopApplicationID = ($Parameters | Where-Object -FilterScript {$_.Name -eq $Tile}).AppID
if (-not ($Group.DesktopApplicationTile | Where-Object -FilterScript {$_.DesktopApplicationID -eq $DesktopApplicationID}))
{
# Calculate current filled columns
$CurrentColumns = @($Group.DesktopApplicationTile.Column)
# Calculate current free columns and take the first one
$Column = (Compare-Object -ReferenceObject $ValidColumns -DifferenceObject $CurrentColumns).InputObject | Select-Object -First 1
# If filled cells contain desired ones assign the first free column
if ($CurrentColumns -contains $Parameter.Column)
{
$Parameter.Column = $Column
}
$Group.AppendChild((Add-Tile @Parameter)) | Out-Null
}
}
else
{
# Create the "Sophia Script" group
[Xml.XmlElement]$Group = $XML.CreateElement("start:Group", $StartLayoutNS)
$Group.SetAttribute("Name","Sophia Script")
$Group.AppendChild((Add-Tile @Parameter)) | Out-Null
$XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.AppendChild($Group) | Out-Null
}
}
$XML.Save($StartLayout)
}
end
{
# Temporarily disable changing the Start menu layout
if (-not (Test-Path -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer))
{
New-Item -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Force
}
New-ItemProperty -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Name LockedStartLayout -Value 1 -Force
New-ItemProperty -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Name StartLayoutFile -Value $StartLayout -Force
Start-Sleep -Seconds 3
# Restart the Start menu
Stop-Process -Name StartMenuExperienceHost -Force -ErrorAction Ignore
Start-Sleep -Seconds 3
# Open the Start menu to load the new layout
$wshell = New-Object -ComObject WScript.Shell
$wshell.SendKeys("^{ESC}")
Start-Sleep -Seconds 3
# Enable changing the Start menu layout
Remove-ItemProperty -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Name LockedStartLayout -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Name StartLayoutFile -Force -ErrorAction Ignore
Remove-Item -Path $StartLayout -Force
Stop-Process -Name StartMenuExperienceHost -Force -ErrorAction Ignore
Start-Sleep -Seconds 3
# Open the Start menu to load the new layout
$wshell = New-Object -ComObject WScript.Shell
$wshell.SendKeys("^{ESC}")
}
Создаваемые задания в планировщике заданий
Для начала разберём две задачи по автоматизации очистки папок %TEMP% и %SystemRoot%SoftwareDistributionDownload. Эти папки полезно очищать по расписанию, чтобы они не разрастались. На текущий момент папка временных файлов самоочищается раз в 60 дней, а папка, куда скачиваются установочные файлы для обновлений, — раз в 90 дней.
По завершении задания были добавлены нативные всплывающие тосты, так сказать, из информационно-эстетических соображений.
Windows 10 позволяет генерировать такие тосты очень просто. Пример всплывающего тоста, как на картинке выше:
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
[xml]$ToastTemplate = @"
<toast duration="Long">
<visual>
<binding template="ToastGeneric">
<text>Уведомление</text>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true">Кэш обновлений Windows успешно удален</text>
</subgroup>
</group>
</binding>
</visual>
<audio src="ms-winsoundevent:notification.default" />
</toast>
"@
$ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New()
$ToastXml.LoadXml($ToastTemplate.OuterXml)
$ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXML)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel").Show($ToastMessage)
В вызове CreateToastNotifier можно указывать приложение, иконка которого будет отображаться в верхнем левом углу тоста и которое будет открываться при нажатии на тост. В данном случае я использовал windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel — «Настройки». Но вы вольны указать любые приложения. Узнать список всех установленных приложений и их AppID нам поможет команда Get-StartApps.
Напомню, что задача по очистке папки для временных файлов удаляет лишь файлы старше суток:
Get-ChildItem -Path $env:TEMP -Recurse -Force | Where-Object {$_.CreationTime -lt (Get-Date).AddDays(-1)} | Remove-Item -Recurse -Force
А задача по очистке папки %SystemRoot%SoftwareDistributionDownload ждёт остановку службы wuauserv (Центр обновления Windows), чтобы в дальнейшем очистить папку
(Get-Service -Name wuauserv).WaitForStatus('Stopped', '01:00:00')
С заданием по запуску очистки диска и DISM с аргументами всё гораздо веселее. Изначально стояла задача просто запускать предзаготовленный пресет настроек для очистки диска и очистку ненужных обновлений, используя DISM: dism.exe /Online /English /Cleanup-Image /StartComponentCleanup /NoRestart.
Но пришлось решать, как заставить задание запускать очистку диска, сворачивать его окно, а потом также минимизировать окно консоли с запущенным DISM.
Сложность состоит в том, что при запуске очистки диска сначала открывается первое окошко со сканированием того, что можно очистить, потом оно закрывается, и только после этого открывается новое окошко (с новым MainWindowHandle) уже непосредственно с очисткой.
Если первое окошко достаточно легко свернуть:
$ProcessInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "$env:SystemRootsystem32cleanmgr.exe"
$ProcessInfo.Arguments = "/sagerun:1337"
$ProcessInfo.UseShellExecute = $true
$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Minimized
То над тем, как свернуть второе, я поломал голову, конечно. После многих попыток хоть за что-то зацепиться, я понял, что:
только MainWindowHandle окна может помочь
Get-Process -Name cleanmgr | Stop-Process -Force
Get-Process -Name Dism | Stop-Process -Force
Get-Process -Name DismHost | Stop-Process -Force
$ProcessInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "$env:SystemRootsystem32cleanmgr.exe"
$ProcessInfo.Arguments = "/sagerun:1337"
$ProcessInfo.UseShellExecute = $true
$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Minimized
$Process = New-Object -TypeName System.Diagnostics.Process
$Process.StartInfo = $ProcessInfo
$Process.Start() | Out-Null
Start-Sleep -Seconds 3
[int]$SourceMainWindowHandle = (Get-Process -Name cleanmgr | Where-Object -FilterScript {$_.PriorityClass -eq "BelowNormal"}).MainWindowHandle
function MinimizeWindow
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
$Process
)
$ShowWindowAsync = @{
Namespace = "WinAPI"
Name = "Win32ShowWindowAsync"
Language = "CSharp"
MemberDefinition = @'
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
'@
}
if (-not ("WinAPI.Win32ShowWindowAsync" -as [type]))
{
Add-Type @ShowWindowAsync
}
$MainWindowHandle = (Get-Process -Name $Process | Where-Object -FilterScript {$_.PriorityClass -eq "BelowNormal"}).MainWindowHandle
[WinAPI.Win32ShowWindowAsync]::ShowWindowAsync($MainWindowHandle, 2)
}
while ($true)
{
[int]$CurrentMainWindowHandle = (Get-Process -Name cleanmgr | Where-Object -FilterScript {$_.PriorityClass -eq "BelowNormal"}).MainWindowHandle
if ($SourceMainWindowHandle -ne $CurrentMainWindowHandle)
{
MinimizeWindow -Process cleanmgr
break
}
Start-Sleep -Milliseconds 5
}
$ProcessInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "$env:SystemRootsystem32dism.exe"
$ProcessInfo.Arguments = "/Online /English /Cleanup-Image /StartComponentCleanup /NoRestart"
$ProcessInfo.UseShellExecute = $true
$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Minimized
$Process = New-Object -TypeName System.Diagnostics.Process
$Process.StartInfo = $ProcessInfo
$Process.Start() | Out-Null
Как видно из кода, $SourceMainWindowHandle первого окна ждёт, пока появится $CurrentMainWindowHandle второго окна, и, если, они не равны, то можно минимизировать новое окно. Дальше уже можно запускать DISM с ключами.
Но на этом я не остановился. Понял, что, возможно, пользователю будет неудобно, что за него решают, когда запускается такая задача (которая иногда может потребовать достаточное количество времени). Поэтому пришла идея сделать интерактивный всплывающий тост!
Как видно на скриншоте, пользователю предоставляются на выбор 3 варианта развития событий: отложить вопрос на 1, 30 минут или 4 часа, полностью отклонить предложение (тогда задача запустится через 30 дней) или запустить.
Как устроено это окно. Это всё тот же тост, но, чтобы создать кнопку, запускающую что-либо, кроме открытия страницы в браузере, необходимо сначала зарегистрировать новый протокол. В примере ниже показывается, как я регистрирую протокол WindowsCleanup:
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup))
{
New-Item -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Force
}
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name "(default)" -PropertyType String -Value "URL:WindowsCleanup" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name "URL Protocol" -Value "" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name EditFlags -PropertyType DWord -Value 2162688 -Force
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOTshellopencommand))
{
New-item -Path Registry::HKEY_CLASSES_ROOTWindowsCleanupshellopencommand -Force
}
# If "Run" clicked run the "Windows Cleanup" task
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanupshellopencommand -Name "(default)" -PropertyType String -Value 'powershell.exe -Command "& {Start-ScheduledTask -TaskPath ''Sophia Script'' -TaskName ''Windows Cleanup''}"' -Force
А потом привязываю его на кнопку запуска:
<action arguments=»WindowsCleanup:» content=»$($Localization.Run)» activationType=»protocol»/>
Всё вместе выглядит так:
# Persist the Settings notifications to prevent to immediately disappear from Action Center
if (-not (Test-Path -Path "HKCU:SOFTWAREMicrosoftWindowsCurrentVersionNotificationsSettingswindows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel"))
{
New-Item -Path "HKCU:SOFTWAREMicrosoftWindowsCurrentVersionNotificationsSettingswindows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel" -Force
}
New-ItemProperty -Path "HKCU:SOFTWAREMicrosoftWindowsCurrentVersionNotificationsSettingswindows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel" -Name ShowInActionCenter -PropertyType DWord -Value 1 -Force
# Register the "WindowsCleanup" protocol to be able to run the scheduled task upon clicking on the "Run" button
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup))
{
New-Item -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Force
}
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name "(default)" -PropertyType String -Value "URL:WindowsCleanup" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name "URL Protocol" -Value "" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name EditFlags -PropertyType DWord -Value 2162688 -Force
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOTshellopencommand))
{
New-item -Path Registry::HKEY_CLASSES_ROOTWindowsCleanupshellopencommand -Force
}
# If "Run" clicked run the "Windows Cleanup" task
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanupshellopencommand -Name "(default)" -PropertyType String -Value 'powershell.exe -Command "& {Start-ScheduledTask -TaskPath ''Sophia Script'' -TaskName ''Windows Cleanup''}"' -Force
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
[xml]$ToastTemplate = @"
<toast duration="Long" scenario="reminder">
<visual>
<binding template="ToastGeneric">
<text>$($Localization.CleanupTaskNotificationTitle)</text>
<group>
<subgroup>
<text hint-style="title" hint-wrap="true">$($Localization.CleanupTaskNotificationEventTitle)</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true">$($Localization.CleanupTaskNotificationEvent)</text>
</subgroup>
</group>
</binding>
</visual>
<audio src="ms-winsoundevent:notification.default" />
<actions>
<input id="SnoozeTimer" type="selection" title="$($Localization.CleanupTaskNotificationSnoozeInterval)" defaultInput="1">
<selection id="1" content="$($Localization.Minute)" />
<selection id="30" content="$($Localization.Minute)" />
<selection id="240" content="$($Localization.Minute)" />
</input>
<action activationType="system" arguments="snooze" hint-inputId="SnoozeTimer" content="" id="test-snooze"/>
<action arguments="WindowsCleanup:" content="$($Localization.Run)" activationType="protocol"/>
<action arguments="dismiss" content="" activationType="system"/>
</actions>
</toast>
"@
$ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New()
$ToastXml.LoadXml($ToastTemplate.OuterXml)
$ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXML)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel").Show($ToastMessage)
Функция ассоциации файлов
Как известно, начиная с Windows 8 невозможно самостоятельно ассоциировать какое-либо расширение с программой, не вычислив правильный хэш. Как выяснилось, Microsoft проводит манипуляции с захардоженной строкой «User Choice set via Windows User Experience {D18B6DD5-6124-4341-9318-804003BAFA0B}».
Пользователь Danyfirex смог реализовать правильное вычисление хэш-суммы на чистом PowerShell, но, к сожалению, после проведённых тестов выяснилось, что сам PowerShell 5.1 считает его неправильно, поэтому я вынужден был использовать код другого разработчика с алгоритмом, реализованным на чистом C#. Крайне быстро! Функция огромная, поэтому просто оставлю просто ссылку на код.
Автоматизация установки бесплатного расширения для встроенного UWP-приложения Фотографии
Еще одна забавная, но крайне полезная функция даёт возможность открывать файлы формата .heic и .heif.
Расширение крайне полезное, так как все современные телефоны умеют делать фотографии в формате HEIC, но по умолчанию Windows 10 не умеет открывать такие файлы, предлагая купить расширение в Microsoft Store по цене в 0,99 $. Но мало кто знает, что есть скрытая страница от поиска этого же самого расширения, но предназначенного для OEM-производителей. Эту же страницу можно открыть вручную, выполнив через Win+R или через PowerShell: ms-windows-store://pdp/?ProductId=9n4wgh0z6vhq
Для скачивания установочного пакета на помощь приходит всеми известный сайт https://store.rg-adguard.net. Он позволяет, зная ID страницы, получать временные прямые ссылки на установочные пакеты. Значит, можно распарсить.
$API = "https://store.rg-adguard.net/api/GetFiles"
# HEVC Video Extensions from Device Manufacturer
$ProductURL = "https://www.microsoft.com/store/productId/9n4wgh0z6vhq"
$Body = @{
"type" = "url"
"url" = $ProductURL
"ring" = "Retail"
"lang" = "en-US"
}
$Raw = Invoke-RestMethod -Method Post -Uri $API -ContentType 'application/x-www-form-urlencoded' -Body $Body
# Parsing the page
$Raw | Select-String -Pattern '<tr style.*<a href="(?<url>.*)"s.*>(?<text>.*)</a>' -AllMatches | ForEach-Object -Process {$_.Matches} | ForEach-Object -Process {
$TempURL = $_.Groups[1].Value
$Package = $_.Groups[2].Value
if ($Package -like "Microsoft.HEVCVideoExtension_*_x64__8wekyb3d8bbwe.appx")
{
[PSCustomObject]@{
PackageName = $Package
PackageURL = $TempURL
}
}
}
Дальше уже дело техники сохранить и установить скачанный пакет.
Автопродление имен функций по введённым буквам, содержащимся в названии функции или её аргумента
Это последняя значимая функция, добавленная в версию 5.10. Пользователи попросили добавить автопродление функций и их аргументов с помощью табуляции, вводя буквы, содержащиеся в названии функции или её аргументов.
Проблема в том, что до этого была лишь возможность вручную указывать функции и их аргументы а-ля .Sophia.ps1 -Functions «DiagTrackService -Disable», «DiagnosticDataLevel -Minimal», UninstallUWPApps.
То есть ни о каком автопродлении речи и не шло: пользователю приходилось или запоминать имя функции и её аргумент, или копировать вручную данную комбинацию из пресет-файла. То ли дело сейчас!
Чтобы заработала сия шайтан-машина, пришлось прибегнуть к Register-ArgumentCompleter.
Весь код сосредоточен в отдельном файле, и не получится его поместить в текущий пресет-файл: файл необходимо вызывать с использованием dot sourcing. Одним словом, пришлось в ScriptBlock для argumentcompleter перебирать все возможные варианты конструкций вида «функция-аргумент» и просто «функция», если у последней нет собственного аргумента.
Теперь, чтобы вызвать, допустим, функцию по удалению UWP-приложений, можно ввести (после загрузки Functions.ps1) So<tab> -Fu<tab> uwp<tab>.
Крайне жутко выглядит, но стало гораздо удобнее.
Ну, а закончу рассказ на том, что даже сборка прикрепляемых архивов на странице релизов стала осуществляться с помощью конфига Github Actions. Как можно заметить, для создания архива под версию для PowerShell 7 приходится выкачивать две библиотеки с ресурсов Microsoft, так как загрузить файлы больше 25 МБ в репозиторий невозможно. Автоматизируй автоматизацию!
Итоги
Это были крайне плодотворные полгода. У нас такое ощущение, что мы прошли PowerShell на уровне «Ultra Violence». Ну, а что дальше? Параллельно я прорабатываю вариант, как реализовать, используя текущий паттерн взаимодействия пользователя со скриптом, настройку офлайновых образов WIM. Но главный приоритет для нас сейчас, конечно, — разработка SophiApp.
Цель проекта — показать, как, по нашему мнению, должен выглядеть, чувствоваться и каким функционалом обладать так называемый твикер для Windows 10. Идей — просто огромное количество! Хотя у нас нет опыта в разработке и нас всего лишь двое, а весь код на SophiApp пишет в одиночку Дмитрий, возможно, летом уже появится первый рабочий билд. Но это уже совсем другая история.
Хочу выразить огромную благодарность также пользователям forum.ru-board westlife и iNNOKENTIY21: ребят, без вашей помощи и подсказок, всё было бы по-другому! А логотип нарисовала художница tea_head, за что ей тоже спасибо. Скрины, использованные в материале, взяты из мультфильма Коргот-варвар. Группа в Telegram. Любите Windows 10, настраивайте её с умом и до новых встреч!
А если хотите прокачать себя, например получить навыки пентестера и зарабатывать на уязвимостях, или подтянуть знания алгоритмов и структур данных — приходите учиться в SkillFactory, будет сложно, но интересно!
Узнайте, как прокачаться и в других специальностях или освоить их с нуля:
-
Профессия Data Scientist
-
Профессия Data Analyst
-
Курс по Data Engineering
Другие профессии и курсы
Настройки Windows 10: часть III, или куда приводят скрипты +28
Системное администрирование, Разработка под Windows, Читальный зал, PowerShell, Блог компании SkillFactory
Рекомендация: подборка платных и бесплатных курсов 3D-моделирования — https://katalog-kursov.ru/
Здравствуйте, товарищи! Прошло чуть больше полугода после выхода предыдущей статьи о Windows 10 Sophia Script — скрипте, который за прошедшие годы стал самым крупным (а их осталось всего два) опенсорс-проектом по персонализации и настройке Windows 10, а также автоматизации рутинных задач. В статье я расскажу, что изменилось с момента релиза версии, описываемой в статье от 29.09.2020, с какими трудностями мы столкнулись, и куда всё движется.
Как всё начиналось
Разработка наброска скрипта берёт своё начало в те далёкие времена, когда после года работы экономистом в отделе проектирования птицефабрики в одной организации я решил перейти в местный отдел IT.
Перейдя на новое место, я предложил автоматизировать настройку пользовательских ОС. Так, через пару недель, появился первый прародитель данного модуля — примитивный .reg-файл для настройки Windows 8.1. Но я и ему был рад, так как всё было в новинку.
Так продолжалось, наверное, год, пока я не понял, что упёрся в тупик и надо менять язык: начал готовить «батник».
В первый день выхода Windows 10 я сразу же «пересел» на неё, поняв, что Windows 8.1 осталась для Microsoft в прошлом. Со временем же «батник» рос, «мужал», разрастался и в какой-то момент даже стал дёргать другой интерпретатор, powershell.exe. Скорость работы падала, и я понимал, что придётся учить PowerShell, так как batch уже не удовлетворяет моим маниакальным запросам автоматизировать всё при настройке ОС.
Как сейчас помню, в феврале 2017 года я сел читать первую статью по запросу «как внести данные в реестр с помощью PowerShell». Уже к лету 2017 года я значительно продвинулся в переписывании всех имеющих функций из «батника» в новый скрипт.
Изначально, конечно, скрипт состоял лишь из одного файла с расширением .ps1. Пользователям приходилось править код и комментировать целые функции, чтобы настроить под себя. То ещё удовольствие было…
Помню, как первый раз почувствовал, что я делаю что-то полезное, когда некто создал issue с просьбой указывать, что я исправляю, когда перезаписываю файлы на GitHub. Пришлось вести журнал изменений.
В таком неспешном темпе разработка шла до августа 2019 года, когда я решил поделиться своими наработками здесь. Хотя я читаю Хабр с года эдак 2007-го, зарегистрировался лишь в 2016-м.
Немного облагородил код (ага, 10 раз), добавил описания на английском языке и накатал крохотную статью о своей pet-разработке. Удивительно, но статью пропустили, она попала в бездну, и я сел ждать.
Как сейчас помню: сижу на сеансе в кинотеатре, и приходит уведомление на почту о новом комментарии к моей статье. Так, стоп! Её одобрили?!
Я не успевал отвечать на комментарии! Это была какая-то эйфория. Какой там фильм?! — меня на Хабр пригласили прямым инвайтом! Фурор! Даже код не обо…ли (а там был кровавый мрак) и вообще любезно приняли.
Самым неожиданным поворотом стало то, что через 5 дней после публикации мне написал некий Дмитрий (@oz-zo), прочитавший моё сетование на то, что у меня не хватает знаний, чтобы сделать графическую версию скрипта, даже хотя бы на Windows.Forms. Я был приятно удивлён, что есть ещё один старый безумец. Как выяснилось, старый, но не бесполезный!
Познакомившись, мы запланировали всё сделать примерно за 3 месяца на Windows.Forms, но наше приключение затянулось… больше чем на 1,5 года: лишь в этом месяце мы вышли на финишную прямую по созданию графической версии моего скрипта — SophiApp. Но это уже другая история, и, когда будет что показать, я обязательно расскажу, что мы пережили за время разработки, поделившись нашими инфернальными набросками и наработками.
С того времени как я познакомился с Дмитрием, разработка пошла быстрее: он внёс огромный вклад в создание новых функций, которых не было ни у кого: все графические функции с использованием WPF и логику к ним написал именно он; я лишь объяснил, как получать данные.
Немаловажным событием стало также знакомство с Дэвидом из Канады, который решил сделать самостоятельно
графическую надстройку для Sophia Script
, Sophia Script Wrapper, для повышения удобства редактирования пресет-файла. В текущем варианте пользователь импортирует пресет-файл скрипта, и в программе расставляются радиокнопки в зависимости от закомментированных и раскомментированных функций. Дальше можно настроить под себя и запустить выполнение настроенного пресет-файла.
Хотя Дэвиду уже нормально так, программировать он сел лишь недавно, окончив курсы. Но его программа выполняет ту задачу, для которой её и написали. Одним словом, люди пользуются.
Что поменялось в скрипте
За время, прошедшее с момента выхода прошлой статьи в сентябре, много воды утекло. Скрипт уже и не узнать. Больше 12 000 строк кода… Самые интересные изыскания пришлись на удаление UWP-приложений и закрепление ярлыков на начальный экран.
Напомню, какие версии Windows 10 поддерживает скрипт на данный момент.
Версия |
Маркетинговое название |
Билд |
Архитектура |
Издания |
21H1 |
Spring 2021 Update |
19043 |
x64 |
Home/Pro/Enterprise |
20H2 |
October 2020 Update |
19042 |
x64 |
Home/Pro/Enterprise |
2004 |
May 2020 Update |
19041 |
x64 |
Home/Pro/Enterprise |
1809 |
LTSC Enterprise 2019 |
17763 |
x64 |
Enterprise |
А теперь пройдёмся по всем доработанным и новым функциям.
Функции касающиеся манипуляций с UWP-приложениями
Наверное, вы уже заметили, что список стал локализованным. Также хочется добавить, что список генерируется динамически, загружая лишь установленные пакеты UWP-приложений в соответствии с текущей локализацией. Как это реализовано?
Свойство DisplayName, которое содержит локализованное имя пакета, находится лишь в одном классе (Get-AppxPackage вам никак тут не поможет, к сожалению):
«Windows.Management.Deployment.PackageManager»
[Windows.Management.Deployment.PackageManager, Windows.Web, ContentType = WindowsRuntime]::new().FindPackages() | Select-Object -Property DisplayName -ExpandProperty Id | Select-Object -Property Name, DisplayName
На выходе вы получите что-то вроде этого (простыню кода прячу под спойлер)
Name DisplayName
---- -----------
1527c705-839a-4832-9118-54d4Bd6a0c89
c5e2524a-ea46-4f67-841f-6a9465d9d515 Проводник
E2A4F912-2574-4A75-9BB0-0D023378592B Сопоставитель приложений
F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE Диалоговое окно "Добавить рекомендованные папки"
Microsoft.AAD.BrokerPlugin Учетная запись компании или учебного заведения
Microsoft.AccountsControl Электронная почта и учетные записи
Microsoft.AsyncTextService AsyncTextService
Microsoft.BioEnrollment Настройка Windows Hello
Microsoft.CredDialogHost Диалоговое окно учетных данных
Microsoft.ECApp Управление глазами
Microsoft.LockApp Экран блокировки Windows по умолчанию
Microsoft.MicrosoftEdgeDevToolsClient Клиент средств разработчика для Microsoft Edge
Microsoft.MicrosoftEdge
Microsoft.Win32WebViewHost Веб-средство просмотра классических приложений
Microsoft.Windows.Apprep.ChxApp SmartScreen Защитника Windows
Microsoft.Windows.AssignedAccessLockApp Приложение "Блокировка" при ограниченном доступе
Microsoft.Windows.CallingShellApp Видеозвонки
Microsoft.Windows.CapturePicker CapturePicker
Microsoft.Windows.CloudExperienceHost Ваша учетная запись
Microsoft.Windows.ContentDeliveryManager Содержимое, предоставленное корпорацией Майкрософт
Microsoft.Windows.NarratorQuickStart Экранный диктор
Microsoft.Windows.OOBENetworkCaptivePortal Поток портала авторизации
Microsoft.Windows.OOBENetworkConnectionFlow Последовательность действий при сетевом подключении
Microsoft.Windows.ParentalControls Функции семьи учетных записей Майкрософт
Microsoft.Windows.PeopleExperienceHost Windows Shell Experience
Microsoft.Windows.PinningConfirmationDialog PinningConfirmationDialog
Microsoft.Windows.Search Windows Search
Microsoft.Windows.SecHealthUI Безопасность Windows
Microsoft.Windows.SecureAssessmentBrowser Тестирование
Microsoft.Windows.ShellExperienceHost Windows Shell Experience
Microsoft.Windows.StartMenuExperienceHost Запустить
Microsoft.Windows.XGpuEjectDialog Безопасное извлечение устройства
Microsoft.XboxGameCallableUI Xbox Game UI
MicrosoftWindows.Client.CBS Windows Feature Experience Pack
MicrosoftWindows.UndockedDevKit UDK Package
NcsiUwpApp NcsiUwpApp
Windows.CBSPreview Предварительный просмотр штрихкодов Windows
windows.immersivecontrolpanel Параметры
Windows.PrintDialog PrintDialog
Microsoft.Services.Store.Engagement Microsoft Engagement Framework
Microsoft.Services.Store.Engagement Microsoft Engagement Framework
Microsoft.UI.Xaml.2.0 Microsoft.UI.Xaml.2.0
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.Advertising.Xaml Microsoft Advertising SDK for XAML
Microsoft.NET.Native.Framework.2.2 Microsoft .Net Native Framework Package 2.2
Microsoft.NET.Native.Framework.2.2 Microsoft .Net Native Framework Package 2.2
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.NET.Native.Runtime.2.2 Microsoft .Net Native Runtime Package 2.2
Microsoft.NET.Native.Runtime.2.2 Microsoft .Net Native Runtime Package 2.2
Microsoft.VCLibs.140.00.UWPDesktop Microsoft Visual C++ 2015 UWP Desktop Runtime Package
Microsoft.VCLibs.140.00.UWPDesktop Microsoft Visual C++ 2015 UWP Desktop Runtime Package
Microsoft.UI.Xaml.2.1 Microsoft.UI.Xaml.2.1
Microsoft.UI.Xaml.2.1 Microsoft.UI.Xaml.2.1
Microsoft.UI.Xaml.2.0 Microsoft.UI.Xaml.2.0
Microsoft.UI.Xaml.2.3 Microsoft.UI.Xaml.2.3
Microsoft.UI.Xaml.2.3 Microsoft.UI.Xaml.2.3
Microsoft.UI.Xaml.2.4 Microsoft.UI.Xaml.2.4
Microsoft.UI.Xaml.2.4 Microsoft.UI.Xaml.2.4
Microsoft.ScreenSketch Набросок на фрагменте экрана
Microsoft.NET.Native.Framework.1.7 Microsoft .Net Native Framework Package 1.7
Microsoft.NET.Native.Framework.1.7 Microsoft .Net Native Framework Package 1.7
Microsoft.NET.Native.Runtime.1.7 Microsoft .Net Native Runtime Package 1.7
Microsoft.NET.Native.Runtime.1.7 Microsoft .Net Native Runtime Package 1.7
Microsoft.VCLibs.120.00 Microsoft Visual C++ Runtime Package
Microsoft.VCLibs.120.00 Microsoft Visual C++ Runtime Package
Microsoft.VCLibs.140.00.UWPDesktop Microsoft Visual C++ 2015 UWP Desktop Runtime Package
Microsoft.VCLibs.140.00.UWPDesktop Microsoft Visual C++ 2015 UWP Desktop Runtime Package
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.VCLibs.140.00 Microsoft Visual C++ 2015 UWP Runtime Package
Microsoft.WebpImageExtension Расширения для изображений Webp
Microsoft.DesktopAppInstaller Установщик приложения
Microsoft.NET.Native.Framework.2.2 Microsoft .Net Native Framework Package 2.2
Microsoft.NET.Native.Framework.2.2 Microsoft .Net Native Framework Package 2.2
AppUp.IntelGraphicsExperience Центр управления графикой Intel®
Microsoft.Windows.StartMenuExperienceHost Запустить
Microsoft.Windows.ShellExperienceHost Windows Shell Experience
Microsoft.Windows.AssignedAccessLockApp Приложение "Блокировка" при ограниченном доступе
Microsoft.WindowsTerminal Windows Terminal
Microsoft.AV1VideoExtension AV1 Video Extension
Microsoft.HEIFImageExtension Расширения для изображений HEIF
Microsoft.Windows.Photos Фотографии (Майкрософт)
Microsoft.UI.Xaml.2.5 Microsoft.UI.Xaml.2.5
Microsoft.UI.Xaml.2.5 Microsoft.UI.Xaml.2.5
Microsoft.WindowsStore Microsoft Store
Microsoft.StorePurchaseApp Узел для покупок в Store
Microsoft.LanguageExperiencePackru-RU Пакет локализованного интерфейса на русском
Microsoft.MicrosoftEdge Microsoft Edge
Microsoft.VP9VideoExtensions Расширения для VP9-видео
MicrosoftWindows.Client.WebExperience Windows Web Experience Pack
Microsoft.WebMediaExtensions Расширения для интернет-мультимедиа
Microsoft.HEVCVideoExtension Расширения для видео HEVC от производителя устройства
MicrosoftWindows.Client.CBS Windows Feature Experience Pack
Microsoft.MicrosoftEdge.Stable Microsoft Edge
Хоть на картинке и не видно, но кнопка «Для всех пользователей» была тоже полностью переписана. Раньше она совершенно неправильно работала. Сейчас же её логика приведена к должному функционалу. По умолчанию при загрузке формы отображается список приложений для текущего пользователя (все системные пакеты и Microsoft Store исключены из списка, так что удалить хоть что-то важное не получится никак, в отличие, кстати, от всех других скриптов в Интернете). При нажатии на кнопку «Для всех пользователей» происходит динамическая перегенерация списка с учётом установленных пакетов во всех учётных записях. То есть вы можете удалить все приложения для текущего пользователя, и форма отобразится пустой, но при запуске функции с ключом «-ForAllUsers» отобразится список пакетов для всех учётных записей.
Как-то меня попросили добавить поддержку PowerShell 7. И всё это было бы смешно, когда бы не было так грустно…
Во-первых, ни для кого не будет секретом, что, хотя в PowerShell 7 исправили очень много багов, в нынешнем виде очень далёк от финальной версии, ведь там до сих пор даже не работает командлет Get-ComputerRestorePoint из коробки. И (в качестве временного решения) Microsoft предложил загружать в сессию недостающие модули из папки PowerShell 5.1, используя аргумент -UseWindowsPowerShell.
Таким образом, мне приходится загружать модули Microsoft.PowerShell.Management, PackageManagement, Appx, чтобы воссоздать работоспособность скрипта на PowerShell 7:
Import-Module -Name Microsoft.PowerShell.Management, PackageManagement, Appx -UseWindowsPowerShell
Во-вторых, код для получения локализованных имен UWP-пакетов не работает в PowerShell 7 вообще, так как Microsoft решил не включать библиотеки WinRT в релизы PowerShell 7, но вынес разработку на отдельные ресурсы: WinRT и Windows.SDK. Это упомянул и Steven Lee в обсуждении на GitHub, а также уведомил, что команда PowerShell решила не включать в дальнейшем в релизы эти библиотеки. Поэтому, чтобы вызвать необходимые API, мне приходится хранить в папке две библиотеки по 26 МБ и 284 КБ. Тут остаётся лишь поставить мем с пингвином.
Код для получения локализованных имен UWP-пакетов на PowerShell 7 выглядит так:
Add-Type -AssemblyName "$PSScriptRootLibrariesWinRT.Runtime.dll"
Add-Type -AssemblyName "$PSScriptRootLibrariesMicrosoft.Windows.SDK.NET.dll"
$AppxPackages = Get-AppxPackage -PackageTypeFilter Bundle -AllUsers
$PackagesIds = [Windows.Management.Deployment.PackageManager]::new().FindPackages().AdditionalTypeData[[Collections.IEnumerable].TypeHandle] | Select-Object -Property DisplayName -ExpandProperty Id | Select-Object -Property Name, DisplayName
foreach ($AppxPackage in $AppxPackages)
{
$PackageId = $PackagesIds | Where-Object -FilterScript {$_.Name -eq $AppxPackage.Name}
if (-not $PackageId)
{
continue
}
[PSCustomObject]@{
Name = $AppxPackage.Name
PackageFullName = $AppxPackage.PackageFullName
DisplayName = $PackageId.DisplayName
}
}
На выходе будет что-то вроде:
Name PackageFullName DisplayName
---- --------------- -----------
RealtekSemiconductorCorp.RealtekAudioControl RealtekSemiconductorCorp.RealtekAudioControl_1.1.137.0_neutral_~_dt26b99r8h8gj Realtek Audio Control
Microsoft.MicrosoftStickyNotes Microsoft.MicrosoftStickyNotes_3.7.142.0_neutral_~_8wekyb3d8bbwe Microsoft Sticky Notes
Microsoft.ScreenSketch Microsoft.ScreenSketch_2020.814.2355.0_neutral_~_8wekyb3d8bbwe Набросок на фрагменте экрана
Microsoft.WindowsCalculator Microsoft.WindowsCalculator_2020.2008.2.0_neutral_~_8wekyb3d8bbwe Windows Calculator
AppUp.IntelGraphicsExperience AppUp.IntelGraphicsExperience_1.100.3282.0_neutral_~_8j3eq9eme6ctt Центр управления графикой Intel®
Microsoft.MicrosoftSolitaireCollection Microsoft.MicrosoftSolitaireCollection_4.7.10142.0_neutral_~_8wekyb3d8bbwe Microsoft Solitaire Collection
Microsoft.DesktopAppInstaller Microsoft.DesktopAppInstaller_2020.1112.20.0_neutral_~_8wekyb3d8bbwe Установщик приложения
Microsoft.WindowsStore Microsoft.WindowsStore_12101.1001.1413.0_neutral_~_8wekyb3d8bbwe Microsoft Store
Microsoft.Windows.Photos Microsoft.Windows.Photos_2020.20120.4004.0_neutral_~_8wekyb3d8bbwe Фотографии (Майкрософт)
Microsoft.WebMediaExtensions Microsoft.WebMediaExtensions_1.0.40471.0_neutral_~_8wekyb3d8bbwe Расширения для интернет-мультим…
Microsoft.WindowsCamera Microsoft.WindowsCamera_2021.105.10.0_neutral_~_8wekyb3d8bbwe Камера Windows
Microsoft.StorePurchaseApp Microsoft.StorePurchaseApp_12103.1001.813.0_neutral_~_8wekyb3d8bbwe Узел для покупок в Store
Microsoft.WindowsTerminal Microsoft.WindowsTerminal_2021.413.2245.0_neutral_~_8wekyb3d8bbwe Windows Terminal
Microsoft.WindowsTerminalPreview Microsoft.WindowsTerminalPreview_2021.413.2303.0_neutral_~_8wekyb3d8bbwe Windows Terminal Preview
Аналогичный подход используется для функции восстановления UWP-приложений. Чтобы восстановить пакет, как известно, необходимо вычленить путь до его манифеста.
Код для получения общего списка всех манифестов выглядит так (можете даже выполнить, если, конечно, не удалили все UWP-приложения):
$Bundles = (Get-AppXPackage -PackageTypeFilter Framework -AllUsers).PackageFullName
Get-ChildItem -Path "HKLM:SOFTWAREClassesLocal SettingsSoftwareMicrosoftWindowsCurrentVersionAppModelPackageRepositoryPackages" | ForEach-Object -Process {
Get-ItemProperty -Path $_.PSPath
} | Where-Object -FilterScript {$_.Path -match "Program Files"} | Where-Object -FilterScript {$_.PSChildName -notin $Bundles} | Where-Object -FilterScript {$_.Path -match "x64"} | ForEach-Object -Process {"$($_.Path)AppxManifest.xml"}
И вы увидите что-то вроде:
C:Program FilesWindowsAppsA025C540.Yandex.Music_4.40.7713.0_x64__vfvw9svesycw6AppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.549981C3F5F10_2.2103.17603.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.BingNews_1.0.6.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.BingWeather_1.0.6.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.DesktopAppInstaller_1.11.10771.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.GamingApp_1.0.1.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.GetHelp_10.2102.40951.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Getstarted_10.2.40751.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.HEIFImageExtension_1.0.40978.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.MicrosoftOfficeHub_18.2008.12711.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.MicrosoftSolitaireCollection_4.9.4072.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.MicrosoftStickyNotes_1.8.15.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Paint_10.2103.1.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.People_10.1909.12456.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.PowerAutomateDesktop_1.0.31.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.ScreenSketch_11.2103.13.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.SkypeApp_14.53.77.0_x64__kzf8qxf38zg5cAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.StorePurchaseApp_12103.1001.8.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Todos_0.41.4902.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.VP9VideoExtensions_1.0.40631.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WebMediaExtensions_1.0.40831.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WebpImageExtension_1.0.32731.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Windows.Photos_2021.21030.17018.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsAlarms_1.0.38.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsCalculator_10.2103.8.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsCamera_2020.503.58.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsmicrosoft.windowscommunicationsapps_16005.13426.20688.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsFeedbackHub_1.2009.10531.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsMaps_1.0.27.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsNotepad_10.2103.6.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsSoundRecorder_1.0.42.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsStore_12103.1001.11.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.WindowsTerminal_1.6.10571.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.Xbox.TCUI_1.23.28002.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.XboxGameOverlay_1.54.4001.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.XboxGamingOverlay_5.621.4072.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.XboxIdentityProvider_12.67.21001.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.XboxSpeechToTextOverlay_1.21.13002.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.YourPhone_1.21022.202.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.ZuneMusic_10.21012.10511.0_x64__8wekyb3d8bbweAppxManifest.xml
C:Program FilesWindowsAppsMicrosoft.ZuneVideo_10.21021.10311.0_x64__8wekyb3d8bbweAppxManifest.xml
PS C:Windowssystem32WindowsPowerShellv1.0>
Но нам надо сопоставить имя пакета, его локализованное имя в системе и путь до манифеста. Искать будем среди пакетов, которые имеют статус «Staged», то есть готовы к восстановлению.
# Тут нельзя напрямую вписать -PackageTypeFilter Bundle, так как иначе не выдается нужное свойство InstallLocation. Только сравнивать с $Bundles
$Bundles = (Get-AppXPackage -PackageTypeFilter Bundle -AllUsers).Name
$AppxPackages = Get-AppxPackage -AllUsers | Where-Object -FilterScript {$_.PackageUserInformation -match "Staged"} | Where-Object -FilterScript {$_.Name -in $Bundles}
$PackagesIds = [Windows.Management.Deployment.PackageManager, Windows.Web, ContentType = WindowsRuntime]::new().FindPackages() | Select-Object -Property DisplayName -ExpandProperty Id | Select-Object -Property Name, DisplayName
foreach ($AppxPackage in $AppxPackages)
{
$PackageId = $PackagesIds | Where-Object -FilterScript {$_.Name -eq $AppxPackage.Name}
if (-not $PackageId)
{
continue
}
[PSCustomObject]@{
Name = $AppxPackage.Name
PackageFullName = $AppxPackage.PackageFullName
DisplayName = $PackageId.DisplayName
AppxManifest = "$($AppxPackage.InstallLocation)AppxManifest.xml"
}
}
Ну, а дальше уже дело техники. Кстати, если вам надо восстановить все возможные пакеты без разбора, то в этом вам поможет.
# Re-register all UWP apps
$Bundles = (Get-AppXPackage -PackageTypeFilter Framework -AllUsers).PackageFullName
Get-ChildItem -Path "HKLM:SOFTWAREClassesLocal SettingsSoftwareMicrosoftWindowsCurrentVersionAppModelPackageRepositoryPackages" | ForEach-Object -Process {
Get-ItemProperty -Path $_.PSPath
} | Where-Object -FilterScript {$_.Path -match "Program Files"} | Where-Object -FilterScript {$_.PSChildName -notin $Bundles} | Where-Object -FilterScript {$_.Path -match "x64"} | ForEach-Object -Process {"$($_.Path)AppxManifest.xml"} | Add-AppxPackage -Register -ForceApplicationShutdown -ForceUpdateFromAnyVersion -DisableDevelopmentMode -Verbose
# Check for UWP apps updates
Get-CimInstance -Namespace "Rootcimv2mdmdmmap" -ClassName "MDM_EnterpriseModernAppManagement_AppManagement01" | Invoke-CimMethod -MethodName UpdateScanMethod
Мы специально не хотели хардкодить список приложений как на удаление, так и на восстановление, так это слишком топорно. Одним словом, получить локализованные имена приложений реально. Дмитрий создал форму на WPF и накатал логику. Не знаю, почему, но мне с Дмитрием потребовалась, наверное, пара недель, учтя все возможные и невозможные условия использования, заставить всё работать как надо.
Точно таким же способом можно выводить список локализованных имён компонентов Windows и дополнительных компонентов.
Работает экстремально медленно, но спасает то, что у меня выводится лишь захардоженный список компонентов, которые можно безболезненно отключить (и включить опять, конечно).
Get-WindowsOptionalFeature -Online | ForEach-Object -Process {Get-WindowsOptionalFeature -FeatureName $_.FeatureName -Online} | Select-Object -Property FeatureName, DisplayName | Format-Table -AutoSize
Интернационализация скрипта
На необходимость этой фичи обратил внимание @FrankSinatra в комментариях. Интернационализация позволяет избавиться от страшной конструкции вида
if ($RU)
{
}
else
{
}
Отныне в корне папки скрипта находятся папки с названием кода локализации: например, ru-RU, en-US и так далее, где внутри находится файл локализации вида UnsupportedOSBitness = The script supports Windows 10 x64 only. Получить значение локализации можно командой $PSUICulture.
Соответственно, чтобы это всё заработало, мы импортируем указанные локализационные файлы, сохраняя строки в переменную так, чтобы можно было вызывать их в скрипте:
# Sophia.psd1
ConvertFrom-StringData -StringData @'
UnsupportedOSBitness = The script supports Windows 10 x64 only
'@
# Sophia.ps1
Import-LocalizedData -BindingVariable Global:Localization -FileName Sophia
$Localization.UnsupportedOSBitness
И в зависимости от текущей локализации системы скрипт сам будет искать нужный файл. И код чище, и людя?м приятнее! Ну, а если необходимой локализации нет, то по умолчанию загружается английская.
На сегодня скрипт локализован на 8 языков: английский, китайский, немецкий, французский, итальянский, русский, украинский, турецкий, испанский и португальский. В будущем всё-таки планирую разместить языковые файлы на Crowdin, но немного душит жаба платить столько денег за некоммерческий продукт.
Закрепление ярлыков на начальном экране
Используется при этом чистый PowerShell. Изначально я использовал стороннюю программу syspin, но возникло желание всё-таки избавиться от неё. Как вы знаете, с выходом Windows 10 October 2018 Microsoft без шума закрыл доступ к API открепления (закрепления) ярлыков от начального экрана и панели задач: отныне это можно сделать лишь вручную.
Ниже приведён пример кода для закрепления (открепления) ярлыка на начальный экран, который когда-то работал. Как можете видеть, в коде используется метод получения локализованной строки, и для этого нам необходимо знать код строки, чтобы вызвать соответствующий пункт контекстного меню. В данном примере, чтобы закрепить ярлык командной строки, мы вызываем строку с кодом 51201, «Закрепить на начальном экране», из библиотеки %SystemRoot%system32shell32.dll.
Получить список всех локализованных строк удобнее всего через стороннюю утилиту ResourcesExtract.
Попытка закрепить ярлык командной строки устаревшим методом:
# Extract a localized string from shell32.dll
$Signature = @{
Namespace = "WinAPI"
Name = "GetStr"
Language = "CSharp"
MemberDefinition = @"
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
public static string GetString(uint strId)
{
IntPtr intPtr = GetModuleHandle("shell32.dll");
StringBuilder sb = new StringBuilder(255);
LoadString(intPtr, strId, sb, sb.Capacity);
return sb.ToString();
}
"@
}
if (-not ("WinAPI.GetStr" -as [type]))
{
Add-Type @Signature -Using System.Text
}
# Pin to Start: 51201
# Unpin from Start: 51394
$LocalizedString = [WinAPI.GetStr]::GetString(51201)
# Trying to pin the Command Prompt shortcut to Start
$Target = Get-Item -Path "$env:APPDATAMicrosoftWindowsStart MenuProgramsSystem ToolsCommand Prompt.lnk"
$Shell = New-Object -ComObject Shell.Application
$Folder = $Shell.NameSpace($Target.DirectoryName)
$file = $Folder.ParseName($Target.Name)
$Verb = $File.Verbs() | Where-Object -FilterScript {$_.Name -eq $LocalizedString}
$Verb.DoIt()
Сейчас консоль вываливается с ошибкой Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED).)
Хотя, как можно заметить, API, конечно, отдаёт глагол контекстного меню «Закрепить на начальном &экране», но не может его выполнить.
Мы знаем, что текущий макет начального экрана можно выгрузить в формате XML. Но, даже если его настроить должным образом, импортировать макет в профиль текущего пользователя не получится: Import-StartLayout -LayoutPath D:Layout.xml импортирует макеты начального экрана и панели задач только для новых пользователей.
Идея заключается в том, чтобы использовать политику «Макет начального экрана» (Prevent users from customizing their Start Screen), отвечающую за подгрузку предзаготовленного макета в формате XML из определённого места. Таким образом, наш хак будет состоять из следующих пунктов:
-
Выгружаем текущий макет начального экрана.
-
Парсим XML, добавляя необходимые нам ярлыки (ссылки должны вести на реально существующие ярлыки), и сохраняем.
-
С помощью политики временно выключаем возможность редактировать макет начального экрана.
-
Перезапускаем меню «Пуск».
-
Программно открываем меню «Пуск», чтобы в реестре сохранился его макет.
-
Выключаем политику, чтобы можно было редактировать макет начального экрана.
-
И открываем меню «Пуск» опять.
Вуаля! В данном примере мы настроили начальный экран на лету, закрепив на него три ярлыка для текущего пользователя: панель управления, устройства и принтеры и PowerShell, причём без перезапуска или выхода из учётной записи.
<#
.SYNOPSIS
Configure the Start tiles
.PARAMETER ControlPanel
Pin the "Control Panel" shortcut to Start
.PARAMETER DevicesPrinters
Pin the "Devices & Printers" shortcut to Start
.PARAMETER PowerShell
Pin the "Windows PowerShell" shortcut to Start
.PARAMETER UnpinAll
Unpin all the Start tiles
.EXAMPLE
.Pin.ps1 -Tiles ControlPanel, DevicesPrinters, PowerShell
.EXAMPLE
.Pin.ps1 -UnpinAll
.EXAMPLE
.Pin.ps1 -UnpinAll -Tiles ControlPanel, DevicesPrinters, PowerShell
.EXAMPLE
.Pin.ps1 -UnpinAll -Tiles ControlPanel
.EXAMPLE
.Pin.ps1 -Tiles ControlPanel -UnpinAll
.LINK
https://github.com/farag2/Windows-10-Sophia-Script
.NOTES
Separate arguments with comma
Current user
#>
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $false,
Position = 0
)]
[switch]
$UnpinAll,
[Parameter(
Mandatory = $false,
Position = 1
)]
[ValidateSet("ControlPanel", "DevicesPrinters", "PowerShell")]
[string[]]
$Tiles,
[string]
$StartLayout = "$PSScriptRootStartLayout.xml"
)
begin
{
# Unpin all the Start tiles
if ($UnpinAll)
{
Export-StartLayout -Path $StartLayout -UseDesktopApplicationID
[xml]$XML = Get-Content -Path $StartLayout -Encoding UTF8 -Force
$Groups = $XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.Group
foreach ($Group in $Groups)
{
# Removing all groups inside XML
$Group.ParentNode.RemoveChild($Group) | Out-Null
}
$XML.Save($StartLayout)
}
}
process
{
# Extract strings from shell32.dll using its' number
$Signature = @{
Namespace = "WinAPI"
Name = "GetStr"
Language = "CSharp"
MemberDefinition = @"
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
public static string GetString(uint strId)
{
IntPtr intPtr = GetModuleHandle("shell32.dll");
StringBuilder sb = new StringBuilder(255);
LoadString(intPtr, strId, sb, sb.Capacity);
return sb.ToString();
}
"@
}
if (-not ("WinAPI.GetStr" -as [type]))
{
Add-Type @Signature -Using System.Text
}
# Extract the localized "Devices and Printers" string from shell32.dll
$DevicesPrinters = [WinAPI.GetStr]::GetString(30493)
# We need to get the AppID because it's auto generated
$Script:DevicesPrintersAppID = (Get-StartApps | Where-Object -FilterScript {$_.Name -eq $DevicesPrinters}).AppID
$Parameters = @(
# Control Panel hash table
@{
# Special name for Control Panel
Name = "ControlPanel"
Size = "2x2"
Column = 0
Row = 0
AppID = "Microsoft.Windows.ControlPanel"
},
# "Devices & Printers" hash table
@{
# Special name for "Devices & Printers"
Name = "DevicesPrinters"
Size = "2x2"
Column = 2
Row = 0
AppID = $Script:DevicesPrintersAppID
},
# Windows PowerShell hash table
@{
# Special name for Windows PowerShell
Name = "PowerShell"
Size = "2x2"
Column = 4
Row = 0
AppID = "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}WindowsPowerShellv1.0powershell.exe"
}
)
# Valid columns to place tiles in
$ValidColumns = @(0, 2, 4)
[string]$StartLayoutNS = "http://schemas.microsoft.com/Start/2014/StartLayout"
# Add pre-configured hastable to XML
function Add-Tile
{
param
(
[string]
$Size,
[int]
$Column,
[int]
$Row,
[string]
$AppID
)
[string]$elementName = "start:DesktopApplicationTile"
[Xml.XmlElement]$Table = $xml.CreateElement($elementName, $StartLayoutNS)
$Table.SetAttribute("Size", $Size)
$Table.SetAttribute("Column", $Column)
$Table.SetAttribute("Row", $Row)
$Table.SetAttribute("DesktopApplicationID", $AppID)
$Table
}
if (-not (Test-Path -Path $StartLayout))
{
# Export the current Start layout
Export-StartLayout -Path $StartLayout -UseDesktopApplicationID
}
[xml]$XML = Get-Content -Path $StartLayout -Encoding UTF8 -Force
foreach ($Tile in $Tiles)
{
switch ($Tile)
{
ControlPanel
{
$ControlPanel = [WinAPI.GetStr]::GetString(12712)
Write-Verbose -Message ("The `"{0}`" shortcut is being pinned to Start" -f $ControlPanel) -Verbose
}
DevicesPrinters
{
$DevicesPrinters = [WinAPI.GetStr]::GetString(30493)
Write-Verbose -Message ("The `"{0}`" shortcut is being pinned to Start" -f $DevicesPrinters) -Verbose
# Create the old-style "Devices and Printers" shortcut in the Start menu
$Shell = New-Object -ComObject Wscript.Shell
$Shortcut = $Shell.CreateShortcut("$env:APPDATAMicrosoftWindowsStart menuProgramsSystem Tools$DevicesPrinters.lnk")
$Shortcut.TargetPath = "control"
$Shortcut.Arguments = "printers"
$Shortcut.IconLocation = "$env:SystemRootsystem32DeviceCenter.dll"
$Shortcut.Save()
Start-Sleep -Seconds 3
}
PowerShell
{
Write-Verbose -Message ("The `"{0}`" shortcut is being pinned to Start" -f "Windows PowerShell") -Verbose
}
}
$Parameter = $Parameters | Where-Object -FilterScript {$_.Name -eq $Tile}
$Group = $XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.Group | Where-Object -FilterScript {$_.Name -eq "Sophia Script"}
# If the "Sophia Script" group exists in Start
if ($Group)
{
$DesktopApplicationID = ($Parameters | Where-Object -FilterScript {$_.Name -eq $Tile}).AppID
if (-not ($Group.DesktopApplicationTile | Where-Object -FilterScript {$_.DesktopApplicationID -eq $DesktopApplicationID}))
{
# Calculate current filled columns
$CurrentColumns = @($Group.DesktopApplicationTile.Column)
# Calculate current free columns and take the first one
$Column = (Compare-Object -ReferenceObject $ValidColumns -DifferenceObject $CurrentColumns).InputObject | Select-Object -First 1
# If filled cells contain desired ones assign the first free column
if ($CurrentColumns -contains $Parameter.Column)
{
$Parameter.Column = $Column
}
$Group.AppendChild((Add-Tile @Parameter)) | Out-Null
}
}
else
{
# Create the "Sophia Script" group
[Xml.XmlElement]$Group = $XML.CreateElement("start:Group", $StartLayoutNS)
$Group.SetAttribute("Name","Sophia Script")
$Group.AppendChild((Add-Tile @Parameter)) | Out-Null
$XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.AppendChild($Group) | Out-Null
}
}
$XML.Save($StartLayout)
}
end
{
# Temporarily disable changing the Start menu layout
if (-not (Test-Path -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer))
{
New-Item -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Force
}
New-ItemProperty -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Name LockedStartLayout -Value 1 -Force
New-ItemProperty -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Name StartLayoutFile -Value $StartLayout -Force
Start-Sleep -Seconds 3
# Restart the Start menu
Stop-Process -Name StartMenuExperienceHost -Force -ErrorAction Ignore
Start-Sleep -Seconds 3
# Open the Start menu to load the new layout
$wshell = New-Object -ComObject WScript.Shell
$wshell.SendKeys("^{ESC}")
Start-Sleep -Seconds 3
# Enable changing the Start menu layout
Remove-ItemProperty -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Name LockedStartLayout -Force -ErrorAction Ignore
Remove-ItemProperty -Path HKCU:SOFTWAREPoliciesMicrosoftWindowsExplorer -Name StartLayoutFile -Force -ErrorAction Ignore
Remove-Item -Path $StartLayout -Force
Stop-Process -Name StartMenuExperienceHost -Force -ErrorAction Ignore
Start-Sleep -Seconds 3
# Open the Start menu to load the new layout
$wshell = New-Object -ComObject WScript.Shell
$wshell.SendKeys("^{ESC}")
}
Создаваемые задания в планировщике заданий
Для начала разберём две задачи по автоматизации очистки папок %TEMP% и %SystemRoot%SoftwareDistributionDownload. Эти папки полезно очищать по расписанию, чтобы они не разрастались. На текущий момент папка временных файлов самоочищается раз в 60 дней, а папка, куда скачиваются установочные файлы для обновлений, — раз в 90 дней.
По завершении задания были добавлены нативные всплывающие тосты, так сказать, из информационно-эстетических соображений.
Windows 10 позволяет генерировать такие тосты очень просто. Пример всплывающего тоста, как на картинке выше:
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
[xml]$ToastTemplate = @"
<toast duration="Long">
<visual>
<binding template="ToastGeneric">
<text>Уведомление</text>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true">Кэш обновлений Windows успешно удален</text>
</subgroup>
</group>
</binding>
</visual>
<audio src="ms-winsoundevent:notification.default" />
</toast>
"@
$ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New()
$ToastXml.LoadXml($ToastTemplate.OuterXml)
$ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXML)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel").Show($ToastMessage)
В вызове CreateToastNotifier можно указывать приложение, иконка которого будет отображаться в верхнем левом углу тоста и которое будет открываться при нажатии на тост. В данном случае я использовал windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel — «Настройки». Но вы вольны указать любые приложения. Узнать список всех установленных приложений и их AppID нам поможет команда Get-StartApps.
Напомню, что задача по очистке папки для временных файлов удаляет лишь файлы старше суток:
Get-ChildItem -Path $env:TEMP -Recurse -Force | Where-Object {$_.CreationTime -lt (Get-Date).AddDays(-1)} | Remove-Item -Recurse -Force
А задача по очистке папки %SystemRoot%SoftwareDistributionDownload ждёт остановку службы wuauserv (Центр обновления Windows), чтобы в дальнейшем очистить папку
(Get-Service -Name wuauserv).WaitForStatus('Stopped', '01:00:00')
С заданием по запуску очистки диска и DISM с аргументами всё гораздо веселее. Изначально стояла задача просто запускать предзаготовленный пресет настроек для очистки диска и очистку ненужных обновлений, используя DISM: dism.exe /Online /English /Cleanup-Image /StartComponentCleanup /NoRestart.
Но пришлось решать, как заставить задание запускать очистку диска, сворачивать его окно, а потом также минимизировать окно консоли с запущенным DISM.
Сложность состоит в том, что при запуске очистки диска сначала открывается первое окошко со сканированием того, что можно очистить, потом оно закрывается, и только после этого открывается новое окошко (с новым MainWindowHandle) уже непосредственно с очисткой.
Если первое окошко достаточно легко свернуть:
$ProcessInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "$env:SystemRootsystem32cleanmgr.exe"
$ProcessInfo.Arguments = "/sagerun:1337"
$ProcessInfo.UseShellExecute = $true
$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Minimized
То над тем, как свернуть второе, я поломал голову, конечно. После многих попыток хоть за что-то зацепиться, я понял, что:
только MainWindowHandle окна может помочь
Get-Process -Name cleanmgr | Stop-Process -Force
Get-Process -Name Dism | Stop-Process -Force
Get-Process -Name DismHost | Stop-Process -Force
$ProcessInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "$env:SystemRootsystem32cleanmgr.exe"
$ProcessInfo.Arguments = "/sagerun:1337"
$ProcessInfo.UseShellExecute = $true
$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Minimized
$Process = New-Object -TypeName System.Diagnostics.Process
$Process.StartInfo = $ProcessInfo
$Process.Start() | Out-Null
Start-Sleep -Seconds 3
[int]$SourceMainWindowHandle = (Get-Process -Name cleanmgr | Where-Object -FilterScript {$_.PriorityClass -eq "BelowNormal"}).MainWindowHandle
function MinimizeWindow
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
$Process
)
$ShowWindowAsync = @{
Namespace = "WinAPI"
Name = "Win32ShowWindowAsync"
Language = "CSharp"
MemberDefinition = @'
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
'@
}
if (-not ("WinAPI.Win32ShowWindowAsync" -as [type]))
{
Add-Type @ShowWindowAsync
}
$MainWindowHandle = (Get-Process -Name $Process | Where-Object -FilterScript {$_.PriorityClass -eq "BelowNormal"}).MainWindowHandle
[WinAPI.Win32ShowWindowAsync]::ShowWindowAsync($MainWindowHandle, 2)
}
while ($true)
{
[int]$CurrentMainWindowHandle = (Get-Process -Name cleanmgr | Where-Object -FilterScript {$_.PriorityClass -eq "BelowNormal"}).MainWindowHandle
if ($SourceMainWindowHandle -ne $CurrentMainWindowHandle)
{
MinimizeWindow -Process cleanmgr
break
}
Start-Sleep -Milliseconds 5
}
$ProcessInfo = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = "$env:SystemRootsystem32dism.exe"
$ProcessInfo.Arguments = "/Online /English /Cleanup-Image /StartComponentCleanup /NoRestart"
$ProcessInfo.UseShellExecute = $true
$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Minimized
$Process = New-Object -TypeName System.Diagnostics.Process
$Process.StartInfo = $ProcessInfo
$Process.Start() | Out-Null
Как видно из кода, $SourceMainWindowHandle первого окна ждёт, пока появится $CurrentMainWindowHandle второго окна, и, если, они не равны, то можно минимизировать новое окно. Дальше уже можно запускать DISM с ключами.
Но на этом я не остановился. Понял, что, возможно, пользователю будет неудобно, что за него решают, когда запускается такая задача (которая иногда может потребовать достаточное количество времени). Поэтому пришла идея сделать интерактивный всплывающий тост!
Как видно на скриншоте, пользователю предоставляются на выбор 3 варианта развития событий: отложить вопрос на 1, 30 минут или 4 часа, полностью отклонить предложение (тогда задача запустится через 30 дней) или запустить.
Как устроено это окно. Это всё тот же тост, но, чтобы создать кнопку, запускающую что-либо, кроме открытия страницы в браузере, необходимо сначала зарегистрировать новый протокол. В примере ниже показывается, как я регистрирую протокол WindowsCleanup:
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup))
{
New-Item -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Force
}
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name "(default)" -PropertyType String -Value "URL:WindowsCleanup" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name "URL Protocol" -Value "" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name EditFlags -PropertyType DWord -Value 2162688 -Force
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOTshellopencommand))
{
New-item -Path Registry::HKEY_CLASSES_ROOTWindowsCleanupshellopencommand -Force
}
# If "Run" clicked run the "Windows Cleanup" task
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanupshellopencommand -Name "(default)" -PropertyType String -Value 'powershell.exe -Command "& {Start-ScheduledTask -TaskPath ''Sophia Script'' -TaskName ''Windows Cleanup''}"' -Force
А потом привязываю его на кнопку запуска:
<action arguments=»WindowsCleanup:» content=»$($Localization.Run)» activationType=»protocol»/>
Всё вместе выглядит так:
# Persist the Settings notifications to prevent to immediately disappear from Action Center
if (-not (Test-Path -Path "HKCU:SOFTWAREMicrosoftWindowsCurrentVersionNotificationsSettingswindows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel"))
{
New-Item -Path "HKCU:SOFTWAREMicrosoftWindowsCurrentVersionNotificationsSettingswindows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel" -Force
}
New-ItemProperty -Path "HKCU:SOFTWAREMicrosoftWindowsCurrentVersionNotificationsSettingswindows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel" -Name ShowInActionCenter -PropertyType DWord -Value 1 -Force
# Register the "WindowsCleanup" protocol to be able to run the scheduled task upon clicking on the "Run" button
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup))
{
New-Item -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Force
}
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name "(default)" -PropertyType String -Value "URL:WindowsCleanup" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name "URL Protocol" -Value "" -Force
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanup -Name EditFlags -PropertyType DWord -Value 2162688 -Force
if (-not (Test-Path -Path Registry::HKEY_CLASSES_ROOTshellopencommand))
{
New-item -Path Registry::HKEY_CLASSES_ROOTWindowsCleanupshellopencommand -Force
}
# If "Run" clicked run the "Windows Cleanup" task
New-ItemProperty -Path Registry::HKEY_CLASSES_ROOTWindowsCleanupshellopencommand -Name "(default)" -PropertyType String -Value 'powershell.exe -Command "& {Start-ScheduledTask -TaskPath ''Sophia Script'' -TaskName ''Windows Cleanup''}"' -Force
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
[xml]$ToastTemplate = @"
<toast duration="Long" scenario="reminder">
<visual>
<binding template="ToastGeneric">
<text>$($Localization.CleanupTaskNotificationTitle)</text>
<group>
<subgroup>
<text hint-style="title" hint-wrap="true">$($Localization.CleanupTaskNotificationEventTitle)</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true">$($Localization.CleanupTaskNotificationEvent)</text>
</subgroup>
</group>
</binding>
</visual>
<audio src="ms-winsoundevent:notification.default" />
<actions>
<input id="SnoozeTimer" type="selection" title="$($Localization.CleanupTaskNotificationSnoozeInterval)" defaultInput="1">
<selection id="1" content="$($Localization.Minute)" />
<selection id="30" content="$($Localization.Minute)" />
<selection id="240" content="$($Localization.Minute)" />
</input>
<action activationType="system" arguments="snooze" hint-inputId="SnoozeTimer" content="" id="test-snooze"/>
<action arguments="WindowsCleanup:" content="$($Localization.Run)" activationType="protocol"/>
<action arguments="dismiss" content="" activationType="system"/>
</actions>
</toast>
"@
$ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::New()
$ToastXml.LoadXml($ToastTemplate.OuterXml)
$ToastMessage = [Windows.UI.Notifications.ToastNotification]::New($ToastXML)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel").Show($ToastMessage)
Функция ассоциации файлов
Как известно, начиная с Windows 8 невозможно самостоятельно ассоциировать какое-либо расширение с программой, не вычислив правильный хэш. Как выяснилось, Microsoft проводит манипуляции с захардоженной строкой «User Choice set via Windows User Experience {D18B6DD5-6124-4341-9318-804003BAFA0B}».
Пользователь Danyfirex смог реализовать правильное вычисление хэш-суммы на чистом PowerShell, но, к сожалению, после проведённых тестов выяснилось, что сам PowerShell 5.1 считает его неправильно, поэтому я вынужден был использовать код другого разработчика с алгоритмом, реализованным на чистом C#. Крайне быстро! Функция огромная, поэтому просто оставлю просто ссылку на код.
Автоматизация установки бесплатного расширения для встроенного UWP-приложения Фотографии
Еще одна забавная, но крайне полезная функция даёт возможность открывать файлы формата .heic и .heif.
Расширение крайне полезное, так как все современные телефоны умеют делать фотографии в формате HEIC, но по умолчанию Windows 10 не умеет открывать такие файлы, предлагая купить расширение в Microsoft Store по цене в 0,99 $. Но мало кто знает, что есть скрытая страница от поиска этого же самого расширения, но предназначенного для OEM-производителей. Эту же страницу можно открыть вручную, выполнив через Win+R или через PowerShell: ms-windows-store://pdp/?ProductId=9n4wgh0z6vhq
Для скачивания установочного пакета на помощь приходит всеми известный сайт https://store.rg-adguard.net. Он позволяет, зная ID страницы, получать временные прямые ссылки на установочные пакеты. Значит, можно распарсить.
$API = "https://store.rg-adguard.net/api/GetFiles"
# HEVC Video Extensions from Device Manufacturer
$ProductURL = "https://www.microsoft.com/store/productId/9n4wgh0z6vhq"
$Body = @{
"type" = "url"
"url" = $ProductURL
"ring" = "Retail"
"lang" = "en-US"
}
$Raw = Invoke-RestMethod -Method Post -Uri $API -ContentType 'application/x-www-form-urlencoded' -Body $Body
# Parsing the page
$Raw | Select-String -Pattern '<tr style.*<a href="(?<url>.*)"s.*>(?<text>.*)</a>' -AllMatches | ForEach-Object -Process {$_.Matches} | ForEach-Object -Process {
$TempURL = $_.Groups[1].Value
$Package = $_.Groups[2].Value
if ($Package -like "Microsoft.HEVCVideoExtension_*_x64__8wekyb3d8bbwe.appx")
{
[PSCustomObject]@{
PackageName = $Package
PackageURL = $TempURL
}
}
}
Дальше уже дело техники сохранить и установить скачанный пакет.
Автопродление имен функций по введённым буквам, содержащимся в названии функции или её аргумента
Это последняя значимая функция, добавленная в версию 5.10. Пользователи попросили добавить автопродление функций и их аргументов с помощью табуляции, вводя буквы, содержащиеся в названии функции или её аргументов.
Проблема в том, что до этого была лишь возможность вручную указывать функции и их аргументы а-ля .Sophia.ps1 -Functions «DiagTrackService -Disable», «DiagnosticDataLevel -Minimal», UninstallUWPApps.
То есть ни о каком автопродлении речи и не шло: пользователю приходилось или запоминать имя функции и её аргумент, или копировать вручную данную комбинацию из пресет-файла. То ли дело сейчас!
Чтобы заработала сия шайтан-машина, пришлось прибегнуть к Register-ArgumentCompleter.
Весь код сосредоточен в отдельном файле, и не получится его поместить в текущий пресет-файл: файл необходимо вызывать с использованием dot sourcing. Одним словом, пришлось в ScriptBlock для argumentcompleter перебирать все возможные варианты конструкций вида «функция-аргумент» и просто «функция», если у последней нет собственного аргумента.
Теперь, чтобы вызвать, допустим, функцию по удалению UWP-приложений, можно ввести (после загрузки Functions.ps1) So<tab> -Fu<tab> uwp<tab>.
Крайне жутко выглядит, но стало гораздо удобнее.
Ну, а закончу рассказ на том, что даже сборка прикрепляемых архивов на странице релизов стала осуществляться с помощью конфига Github Actions. Как можно заметить, для создания архива под версию для PowerShell 7 приходится выкачивать две библиотеки с ресурсов Microsoft, так как загрузить файлы больше 25 МБ в репозиторий невозможно. Автоматизируй автоматизацию!
Итоги
Это были крайне плодотворные полгода. У нас такое ощущение, что мы прошли PowerShell на уровне «Ultra Violence». Ну, а что дальше? Параллельно я прорабатываю вариант, как реализовать, используя текущий паттерн взаимодействия пользователя со скриптом, настройку офлайновых образов WIM. Но главный приоритет для нас сейчас, конечно, — разработка SophiApp.
Цель проекта — показать, как, по нашему мнению, должен выглядеть, чувствоваться и каким функционалом обладать так называемый твикер для Windows 10. Идей — просто огромное количество! Хотя у нас нет опыта в разработке и нас всего лишь двое, а весь код на SophiApp пишет в одиночку Дмитрий, возможно, летом уже появится первый рабочий билд. Но это уже совсем другая история.
Хочу выразить огромную благодарность также пользователям forum.ru-board westlife и iNNOKENTIY21: ребят, без вашей помощи и подсказок, всё было бы по-другому! А логотип нарисовала художница tea_head, за что ей тоже спасибо. Скрины, использованные в материале, взяты из мультфильма Коргот-варвар. Группа в Telegram. Любите Windows 10, настраивайте её с умом и до новых встреч!
А если хотите прокачать себя, например получить навыки пентестера и зарабатывать на уязвимостях, или подтянуть знания алгоритмов и структур данных — приходите учиться в SkillFactory, будет сложно, но интересно!
Узнайте, как прокачаться и в других специальностях или освоить их с нуля:
-
Профессия Data Scientist
-
Профессия Data Analyst
-
Курс по Data Engineering
Другие профессии и курсы
Overview
Native Ads is a component-based ad format that gives publishers the flexibility of placing the individual components of a creative – title, image, logo, description, call to action text – so as to provide the best possible fitment to the look and feel of the rest of the app. This enables the developers to use fonts, colors and animations of their own to stitch unobtrusive user experience in their app while earning high yield from advertising. For advertisers as well, this provides high performing placements since the ads experience is tightly built into the app and users tend to interact a lot more with such sponsored content. According to a report by Mobile Marketing, native in-app ads typically see five times greater engagement than traditional banner ads and, hence, get greater spend from advertisers as well (as per eMarketer and other reports).
Starting now, developers can create Native Ad slots in their apps or games using the latest version of Microsoft Advertising SDK (10.0.4 or later). Microsoft Monetization platform provides developers with the maximum amount of freedom to create their own presentations and is available to a limited set of publishers in a closed pilot. Please contact [email protected] to express your interest to be part of this pilot.
Where Do I Start?
As always, start with downloading the Microsoft Advertising SDK. This provides you the libraries to include Native Ads into your app or game.
Create a “Native” ad unit for your app in ‘Monetize with ads’ section on DevCenter (dev.windows.com). This is the ad unit that you will use in your app when you request for an ad in the code.
How Do I Get Native Ads Integrated into my App?
This section assumes that you are familiar with the Microsoft Advertising SDK for your UWP app or game. If you haven’t played around with this, consider going through the Get Started guide.
To show Native Ads in your app, follow the instructions for project type:
XAML/.NET
HTML/JavaScript
XAML/.NET
This section provides C# examples for your XAML/.NET project. You will need to go through these simple steps to get Native Ads in your code.
Step 1: Setup References
Open your project in Visual Studio. In Reference Manager, expand Universal Windows, click Extensions and then select the check box next to Microsoft Advertising SDK for XAML.
In appropriate code file in your app (for example, in MainPage.xaml.cs), add the following namespace reference.
[code lang=”csharp”]
using Microsoft.Advertising.WinRT.UI;
[/code]
Step 2: Setting up Native Ads Manager
In an appropriate location in your app (for example in MainPage or some other page), declare a NativeAdsManager object and string fields that represent the application ID and ad unit ID for your Native Ad. The following code example assigns the myAppId and myAdUnitId fields to the test values for Native Ads provided in Test Mode values. These values are only used for testing; you must replace them with live values from Windows DevCenter before you publish your app.
[code lang=”csharp”]
NativeAdsManager nativeAdsManager = null;
string appId = «d25517cb-12d4-4699-8bdc-52040c712cab»;
string adUnitId = «test»;
[/code]
In code that runs on startup, instantiate the NativeAdsManager.
[code lang=”csharp”]
// Ad Events
nativeAdsManager = new NativeAdsManager(appId, adUnitId);
[/code]
Step 3: Request for an Ad
When you want to show an ad, request for one using the NativeAdsManager and wire up the events.
[code lang=”csharp”]
nativeAdsManager.RequestAd();
nativeAdsManager.AdReady += NativeAd_OnAdReady;
nativeAdsManager.ErrorOccurred += NativeAd_ErrorOccurred;
[/code]
Step 4: Using components of the Ad to stitch up the experience
Assume you have a XAML page which has various placeholders for Title, Description, Sponsored By, Call To Action of an Ad and a container which contains all these elements. Sample StackPanel containing all the elements.
[code lang=”xml”]
<StackPanel x:Name=»NativeAdContainer» BorderThickness=»2″ BorderBrush=»Azure»>
<StackPanel x:Name=»IconImageContainer» BorderThickness=»2″ BorderBrush=»Azure» Visibility=»Collapsed» >
<Image x:Name=»IconImage» />
</StackPanel>
<TextBox x:Name=»TitleBox» Text=»The title will go here» Margin=»78,0,-78,0″/>
<TextBox x:Name=»DescriptionBox» Text=»The Description will go here» Visibility=»Collapsed» />
<TextBox x:Name=»SponsoredBy» Text=»The SponsoredBy will go here» Visibility=»Collapsed» />
<StackPanel x:Name=»MainImageContainer» BorderThickness=»2″ BorderBrush=»Azure» Visibility=»Collapsed»>
<Image x:Name=»MainImage» Margin=»0,8,0,4″ />
</StackPanel>
<Button x:Name=»CallToAction» Margin=»0,8,0,4″ Visibility=»Collapsed» />
</StackPanel>
[/code]
Based on components of the creative that you want to stitch up in your app, your code may differ. Here is a sample OnAdReady event listener where Title, Description, CallToAction and Image is being used.
[code lang=”csharp”]
void NativeAd_OnAdReady(object sender, object e)
{
NativeAd nativeAd = (NativeAd)e;
TitleBox.Text = nativeAd.Title;
//if description is not null show description textbox
var description = nativeAd.Description;
if (!string.IsNullOrEmpty(description))
{
DescriptionBox.Text = nativeAd.Description;
DescriptionBox.Visibility = Visibility.Visible;
}
//if sponsoredBy is not null show sponsoredBy textbox
var sponsoredBy = nativeAd.SponsoredBy;
if (!string.IsNullOrEmpty(sponsoredBy))
{
SponsoredBy.Text = sponsoredBy;
SponsoredBy.Visibility = Visibility.Visible;
}
//if CallToAction is not null update Button
var callToAction = nativeAd.CallToAction;
if (!string.IsNullOrEmpty(callToAction))
{
CallToAction.Content = callToAction;
CallToAction.Visibility = Visibility.Visible;
}
// Assets consists further information about Ad
var assets = nativeAd.AdditionalAssets;
// Loading images
var icon = nativeAd.IconImage;
if (icon != null)
{
var bitmapImage = new BitmapImage();
bitmapImage.UriSource = new Uri(nativeAd.IconImage.Url);
IconImage.Source = bitmapImage;
// Best view when using the Height and Width of the image given
IconImage.Height = nativeAd.IconImage.Height;
IconImage.Width = nativeAd.IconImage.Width;
IconImageContainer.Visibility = Visibility.Visible;
}
// There might be multiple main images sent by the server
var mainImages = nativeAd.MainImages;
if (mainImages.Count > 0)
{
var mainImage = mainImages[0];
var bitmapImage = new BitmapImage();
bitmapImage.UriSource = new Uri(mainImage.Url);
MainImage.Source = bitmapImage;
// Best view when using the Height and Width of the image given
MainImage.Height = mainImage.Height;
MainImage.Width = mainImage.Width;
MainImageContainer.Visibility = Visibility.Visible;
}
// It is required to show the AdIcon in your container
NativeAdContainer.Children.Add(nativeAd.AdIcon);
// Register any xaml framework element for clicks/impressions
nativeAd.RegisterAdContainer(NativeAdContainer);
[/code]
P.S: The developer is required to “Register” the XAML ad container (any framework Element) with the Native Ads object. This is required for handling impressions and click tracking and is critical for ad earnings. Failure to do so may result in ad-units and advertising payouts being blocked by Microsoft.
HTML/JavaScript
More details on the HTML feature will be coming soon! Please reach out to us ([email protected]) if your apps are in HTML/JS and you need this feature.
Guidelines
Even though the developer has complete control over how to create the ad experience and which components of the creative is displayed to the user, the advertiser’s creative should get its due message out to the user. There is a fine balance that needs to be achieved to reap maximum value from the Native Ad.
Here are some guidelines to ensure the balance.
Required to Show
There are two advertiser assets that must always be shown to the user in your Native Ad design. Failing to include any of these could result in low performance of your ad unit and eventual low (or no) yield. These assets are:
- Ad Title
- Either Distinguishable ad icon (This Ad Icon is sent as part of NativeAd object – property named AdIcon) or Sponsored By or texts such as ‘Sponsored’, ‘Promoted’, ‘Recommended’
Not following these guidelines may result in the removal of the adUnits from the advertising system.
Ad Experience
Your Native Ad should be clearly delineated from the rest of your content and have space around it to prevent accidental clicks. Use border, background or some other treatment to separate the ad content. Always remember, getting user to accidentally click on the ad is not beneficial in the longer term for your ads based revenue and for end user experience.
You should always show the distinguishable “Ad” icon in the ad view. Whenever possible, show the “Sponsored By” field to clearly call out that the content is an ad and provided by an advertiser.
Text Display Requirements
Native Ads should always have the Title displayed. Provide enough space to display at least 25 characters of the title. If the title is longer, ensure to replace the additional text with an ellipsis.
Ensure that the Call-to-Action (CTA) is separated out from the rest of the promotional text from the advertiser.
If you choose the rest of the promotional text (Description) from the ad response, provide space to display at least 75 characters of the same. It’s best to use animations to show the full content of the ad description.
Call-to-Action
Native Ads should always have the CTA displayed to the user as something clickable like a button or hyperlink.
CTA string should always be displayed in its entirety as it is a critical component of the advertiser’s creative.
Learn and Optimize
It is recommended that different ad units are created and used for each different placement of Native Ads in the app. This enables reporting and learning for each placement which then can be used for optimizing each placement separately till optimal performance is achieved.
In case of any further queries, please reach out to [email protected] and we’ll be glad to help you out.
Разработка для Windows 10 – Введение
Этот учебник предназначен для людей, которые хотят научиться разрабатывать приложения для Windows 10. В этом уроке мы собираемся изучить –
- Разработка приложений для Windows 10
- Обновления новой ОС выпущены Microsoft
- Новые функции для разработчиков в обновлениях
Сейчас возможно множество интересных сценариев приложений, которые не были доступны нам в первом выпуске. Microsoft не только добавила новые API, они также расширили существующие API.
Универсальное приложение для Windows
Универсальное приложение для Windows было впервые представлено в Windows 8 как среда выполнения Windows, построенная на платформе универсальных приложений.
Теперь в Windows 10 имя универсальной платформы приложений было изменено на Универсальная платформа Windows (UWP). Вы можете создавать современные и полностью захватывающие приложения, ориентируясь на устройства Windows 10 для Магазина Windows, такие как ПК, планшет, телефон и т. Д.
В Windows 10 вы можете легко разрабатывать приложения для всех устройств, поддерживаемых в Windows 10, с помощью:
- Один набор API
- Один пакет приложений
- И один магазин
Универсальная платформа Windows также поддерживает различные размеры экрана и различные модели взаимодействия, такие как сенсорная панель, мышь и клавиатура, игровой контроллер или ручка.
Характеристики приложений UWP
Вот некоторые характеристики универсальных приложений Windows, которые делают его превосходящим Windows 10.
-
Вы можете ориентироваться на семейства устройств, а не на ОС, например Windows 8.1.
-
Приложения упаковываются и распространяются с использованием формата упаковки .AppX , что обеспечивает беспрепятственное развертывание и обновление приложений.
-
Вы можете отправить свое приложение в магазин Windows, и оно сделает его доступным для всех семейств устройств или только для тех устройств, которые вы выберете. Вы можете легко управлять всеми своими приложениями для устройств Windows в одном месте.
-
Вы можете ограничить доступность вашего приложения определенным семейством устройств.
-
Основные API универсальной платформы Windows (UWP) одинаковы для всех семейств устройств Windows. Таким образом, ваше приложение может работать на всех устройствах Windows 10, если оно использует только основные API.
-
С помощью расширенных SDK вы можете включить свое приложение для определенных устройств.
Вы можете ориентироваться на семейства устройств, а не на ОС, например Windows 8.1.
Приложения упаковываются и распространяются с использованием формата упаковки .AppX , что обеспечивает беспрепятственное развертывание и обновление приложений.
Вы можете отправить свое приложение в магазин Windows, и оно сделает его доступным для всех семейств устройств или только для тех устройств, которые вы выберете. Вы можете легко управлять всеми своими приложениями для устройств Windows в одном месте.
Вы можете ограничить доступность вашего приложения определенным семейством устройств.
Основные API универсальной платформы Windows (UWP) одинаковы для всех семейств устройств Windows. Таким образом, ваше приложение может работать на всех устройствах Windows 10, если оно использует только основные API.
С помощью расширенных SDK вы можете включить свое приложение для определенных устройств.
Выбор развития
Универсальные приложения Windows могут быть созданы на любом из следующих языков –
- C # или Visual Basic с XAML
- JavaScript с HTML
- C ++ с DirectX и / или XAML
Вы также можете писать компоненты на одном языке и использовать их в приложении, разработанном на другом языке.
Разработка для Windows 10 – UWP
Среда выполнения Windows (WinRT) представляет собой платформенно-однородную архитектуру приложений, которая поддерживает разработку на C ++ / CX, C #, VB.NET и JavaScript. Приложения WinRT изначально поддерживают архитектуры как x86, так и ARM. Некоторые важные особенности
-
Впервые он был представлен в Windows Server 2012 в сентябре 2012 года.
-
WinRT API предоставляют доступ ко всем основным функциям платформы, используя JavaScript, C #, Visual Basic и C ++.
-
Компоненты WinRT поддерживают несколько языков и API, таких как родной, управляемый и скриптовый языки.
Впервые он был представлен в Windows Server 2012 в сентябре 2012 года.
WinRT API предоставляют доступ ко всем основным функциям платформы, используя JavaScript, C #, Visual Basic и C ++.
Компоненты WinRT поддерживают несколько языков и API, таких как родной, управляемый и скриптовый языки.
Универсальная платформа Windows (UWP)
Универсальное приложение для Windows построено на универсальной платформе Windows (UWP), которая впервые была представлена в Windows 8 как среда выполнения Windows. В Windows 10 была представлена универсальная платформа Windows (UWP), которая еще больше расширяет модель среды выполнения Windows (WinRT).
-
В Windows 8.1 WinRT впервые был приведен в соответствие между приложениями Windows Phone 8.1 и приложениями Windows 8.1 с помощью универсальных приложений Windows 8 для нацеливания приложений Windows Phone и Windows с использованием общей кодовой базы.
-
Унифицированное ядро Windows 10, которое теперь называется Windows Core, достигло точки, когда UWP теперь предоставляет общую платформу приложений, доступную на каждом устройстве, работающем в Windows 10.
В Windows 8.1 WinRT впервые был приведен в соответствие между приложениями Windows Phone 8.1 и приложениями Windows 8.1 с помощью универсальных приложений Windows 8 для нацеливания приложений Windows Phone и Windows с использованием общей кодовой базы.
Унифицированное ядро Windows 10, которое теперь называется Windows Core, достигло точки, когда UWP теперь предоставляет общую платформу приложений, доступную на каждом устройстве, работающем в Windows 10.
-
UWP может вызывать не только API-интерфейсы WinRT, которые являются общими для всех устройств, но также и API-интерфейсы (включая API-интерфейсы Win32 и .NET), специфичные для семейства устройств, на котором выполняется приложение.
UWP может вызывать не только API-интерфейсы WinRT, которые являются общими для всех устройств, но также и API-интерфейсы (включая API-интерфейсы Win32 и .NET), специфичные для семейства устройств, на котором выполняется приложение.
Устройства, поддерживаемые Windows 10
Приложения Windows 8.1 и Windows Phone 8.1 предназначены для ОС; либо Windows, либо Windows Phone. Приложения Windows 10 не нацелены на ОС, но нацелены на одно или несколько семейств устройств.
Семейства устройств также имеют свои собственные API, которые добавляют функциональность для этого конкретного семейства устройств. Вы можете легко определить все устройства в семействе устройств, на которых ваши приложения могут быть установлены и запущены из Магазина Windows. Вот иерархическое представление семейства устройств.
Преимущества UWP
Универсальная платформа Windows (UWP) предоставляет разработчикам несколько вещей. Они –
- Одна операционная система и одно унифицированное ядро для всех устройств.
- Одна платформа приложений для запуска приложений в каждой семье.
- Один Dev Center для подачи заявки и панель инструментов.
- Один магазин для всех устройств.
Настройка для разработки UWP
Чтобы начать создание собственных приложений универсальной платформы Windows (UWP) для Windows 10, необходимо выполнить следующие шаги.
-
ОС Windows 10 – приложениям UWP для разработки требуется последняя версия Windows. Вы также можете разрабатывать приложения UWP в Windows 8.1, но в Windows Designer Window отсутствует поддержка.
-
Инструменты разработчика для Windows 10 – В Visual Studio 2015 вы можете разрабатывать, кодировать, тестировать и отлаживать свои приложения UWP. Вы можете скачать и установить бесплатное сообщество Microsoft Visual Studio 2015 по адресу https://dev.windows.com/en-us/downloads.
-
Включить режим разработки для Windows 10 –
-
Зайдите в Пуск> Настройки .
-
Выберите Обновление и безопасность .
-
Затем выберите «Для разработчиков» .
-
Нажмите на режим разработчика
-
ОС Windows 10 – приложениям UWP для разработки требуется последняя версия Windows. Вы также можете разрабатывать приложения UWP в Windows 8.1, но в Windows Designer Window отсутствует поддержка.
Инструменты разработчика для Windows 10 – В Visual Studio 2015 вы можете разрабатывать, кодировать, тестировать и отлаживать свои приложения UWP. Вы можете скачать и установить бесплатное сообщество Microsoft Visual Studio 2015 по адресу https://dev.windows.com/en-us/downloads.
Включить режим разработки для Windows 10 –
Зайдите в Пуск> Настройки .
Выберите Обновление и безопасность .
Затем выберите «Для разработчиков» .
Нажмите на режим разработчика
Для приложений UWP важно тестировать свои приложения на устройствах.
-
Регистрация в качестве разработчика приложения. Вы можете начать разработку приложений, но для отправки своих приложений в магазин требуется учетная запись разработчика. Вы можете создать свою учетную запись разработчика здесь https://msdn.microsoft.com/enus/library/windows/apps/bg124287.aspx
Регистрация в качестве разработчика приложения. Вы можете начать разработку приложений, но для отправки своих приложений в магазин требуется учетная запись разработчика. Вы можете создать свою учетную запись разработчика здесь https://msdn.microsoft.com/enus/library/windows/apps/bg124287.aspx
Выполнив описанные выше шаги, вы готовы приступить к разработке приложения универсальной платформы Windows (UWP).
Разработка для Windows 10 – первое приложение
В этой главе мы будем создавать наше первое простое приложение «Hello world» на универсальной платформе Windows (UWP) с использованием XAML и C # в Windows 10. Мы продемонстрируем, как одно приложение UWP, созданное в Visual Studio, можно запускать и выполнять на любом Устройство Windows 10.
Давайте начнем создавать приложение, следуя инструкциям ниже.
-
Запустите Visual Studio 2015.
-
Нажмите на меню « Файл» и выберите « Создать»> «Проект» .
Запустите Visual Studio 2015.
Нажмите на меню « Файл» и выберите « Создать»> «Проект» .
-
Появится следующее диалоговое окно New Project . Вы можете увидеть различные типы шаблонов на левой панели диалогового окна.
Появится следующее диалоговое окно New Project . Вы можете увидеть различные типы шаблонов на левой панели диалогового окна.
-
На левой панели вы можете увидеть дерево. Выберите Универсальный шаблон из Шаблонов> Visual C #> Windows .
-
На центральной панели выберите шаблон « Пустое приложение (универсальная Windows)».
-
Дайте имя проекту, написав UWPHelloWorld в поле Имя .
-
Нажмите OK, чтобы создать новый проект UWP.
На левой панели вы можете увидеть дерево. Выберите Универсальный шаблон из Шаблонов> Visual C #> Windows .
На центральной панели выберите шаблон « Пустое приложение (универсальная Windows)».
Дайте имя проекту, написав UWPHelloWorld в поле Имя .
Нажмите OK, чтобы создать новый проект UWP.
-
Вы можете увидеть недавно созданный проект в обозревателе решений .
-
Это пустое приложение, но оно содержит много файлов, что является минимальным требованием для любого приложения UWP.
-
MainPage.xaml и MainPage.xaml.cs запускаются при запуске приложения.
-
По умолчанию файл MainPage.xaml содержит следующую информацию.
Вы можете увидеть недавно созданный проект в обозревателе решений .
Это пустое приложение, но оно содержит много файлов, что является минимальным требованием для любого приложения UWP.
MainPage.xaml и MainPage.xaml.cs запускаются при запуске приложения.
По умолчанию файл MainPage.xaml содержит следующую информацию.
<Page x:Class = ”UWPHellowWorld.MainPage” xmlns = ”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = ”http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local = ”using:UWPHellowWorld” xmlns:d = ”http://schemas.microsoft.com/expression/blend/2008” xmlns:mc = ”http://schemas.openxmlformats.org/markup-compatibility/2006” mc:Ignorable = ”d”> <Grid Background = ”{ThemeResource ApplicationPageBackgroundThemeBrush}”> </Grid> </Page>
-
Ниже приведена информация по умолчанию, доступная в MainPage.xaml.cs .
Ниже приведена информация по умолчанию, доступная в MainPage.xaml.cs .
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPHellowWorld { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage(){ this.InitializeComponent(); } } }
-
Давайте добавим несколько текстовых блоков, текстовое поле и кнопку, как показано в коде XAML ниже.
Давайте добавим несколько текстовых блоков, текстовое поле и кнопку, как показано в коде XAML ниже.
<Page x:Class = ”UWPHellowWorld.MainPage” xmlns = ”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x = ”http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local = ”using:UWPHellowWorld” xmlns:d = ”http://schemas.microsoft.com/expression/blend/2008” xmlns:mc = ”http://schemas.openxmlformats.org/markup-compatibility/2006” mc:Ignorable = ”d”> <Grid Background = ”{ThemeResource ApplicationPageBackgroundThemeBrush}”> <StackPanel HorizontalAlignment = ”Center”> <TextBlock Text = ”Hello, world!” Margin = ”20” Width = ”200” HorizontalAlignment = ”Left”/> <TextBlock Text = ”Write your name.” Margin = ”20” Width = ”200” HorizontalAlignment = ”Left”/> <TextBox x:Name = ”txtbox” Width = ”280” Margin = ”20” HorizontalAlignment = ”Left”/> <Button x:Name = ”button” Content = ”Click Me” Margin = ”20” Click = ”button_Click”/> <TextBlock x:Name = ”txtblock” HorizontalAlignment = ”Left” Margin = ”20”/> </StackPanel> </Grid> </Page>
- Ниже приведено нажатие кнопки события в C #.
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPHellowWorld { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void button_Click(object sender, RoutedEventArgs e) { if (txtbox.Text != “”) txtblock.Text = “Hello: “ + txtbox.Text; else txtblock.Text = “You have not write your name”; } } }
-
В проекте UWP в окне «Дизайн» доступна опция предварительного просмотра устройства , с помощью которой вы можете легко изменить макет, чтобы соответствовать размеру экрана всех устройств в семействе устройств, на которое вы ориентируетесь для своего приложения.
В проекте UWP в окне «Дизайн» доступна опция предварительного просмотра устройства , с помощью которой вы можете легко изменить макет, чтобы соответствовать размеру экрана всех устройств в семействе устройств, на которое вы ориентируетесь для своего приложения.
-
Вы можете запустить и протестировать свое приложение на локальном компьютере, в симуляторе или эмуляторе, или на удаленном устройстве. Вы можете выбрать целевое устройство из следующего меню, как показано ниже –
Вы можете запустить и протестировать свое приложение на локальном компьютере, в симуляторе или эмуляторе, или на удаленном устройстве. Вы можете выбрать целевое устройство из следующего меню, как показано ниже –
-
Давайте запустим приведенный выше код на локальном компьютере, и вы увидите следующее окно. Теперь напишите любое имя в текстовом поле и нажмите кнопку « Нажмите меня» .
Давайте запустим приведенный выше код на локальном компьютере, и вы увидите следующее окно. Теперь напишите любое имя в текстовом поле и нажмите кнопку « Нажмите меня» .
-
Теперь, если вы хотите протестировать свое приложение на эмуляторе, вы можете выбрать конкретный эмулятор из меню и запустить ваше приложение. Вы увидите следующий эмулятор –
Теперь, если вы хотите протестировать свое приложение на эмуляторе, вы можете выбрать конкретный эмулятор из меню и запустить ваше приложение. Вы увидите следующий эмулятор –
Мы рекомендуем вам выполнить вышеуказанное приложение на разных устройствах.
Разработка Windows 10 – Магазин
Преимущество Магазина Windows для разработчиков заключается в том, что вы можете продавать свое приложение. Вы можете подать отдельную заявку для каждого семейства устройств.
-
В Магазине Windows 10 представлены приложения, чтобы пользователь мог найти ваше приложение.
-
В Windows 8 Магазин был ограничен только приложениями, и Microsoft предоставляет множество магазинов, например, Xbox Music Store, Xbox Game Store и т. Д.
В Магазине Windows 10 представлены приложения, чтобы пользователь мог найти ваше приложение.
В Windows 8 Магазин был ограничен только приложениями, и Microsoft предоставляет множество магазинов, например, Xbox Music Store, Xbox Game Store и т. Д.
-
В Windows 8 все это были разные магазины, но в Windows 10 он называется Windows Store. Он разработан таким образом, чтобы пользователи могли найти полный спектр приложений, игр, песен, фильмов, программного обеспечения и услуг в одном месте для всех устройств Windows 10.
В Windows 8 все это были разные магазины, но в Windows 10 он называется Windows Store. Он разработан таким образом, чтобы пользователи могли найти полный спектр приложений, игр, песен, фильмов, программного обеспечения и услуг в одном месте для всех устройств Windows 10.
монетизация
Монетизация означает продажу вашего приложения на настольных компьютерах, мобильных устройствах, планшетах и других устройствах. Существуют различные способы продать свои приложения и услуги в Магазине Windows, чтобы заработать немного денег.
Вы можете выбрать любой из следующих методов –
-
Самый простой способ – отправить свое приложение в магазин с платными опциями загрузки.
-
Опция Trails, где пользователи могут попробовать ваше приложение, прежде чем покупать его с ограниченными функциональными возможностями.
-
Добавьте рекламу в свои приложения с помощью Microsoft Advertising.
Самый простой способ – отправить свое приложение в магазин с платными опциями загрузки.
Опция Trails, где пользователи могут попробовать ваше приложение, прежде чем покупать его с ограниченными функциональными возможностями.
Добавьте рекламу в свои приложения с помощью Microsoft Advertising.
Microsoft Advertising
Когда вы добавляете рекламу в свое приложение и пользователь нажимает на это объявление, рекламодатель будет платить вам деньги. Microsoft Advertising позволяет разработчикам получать рекламу от рекламной сети Microsoft.
-
Microsoft Advertising SDK для универсальных приложений Windows входит в состав библиотек, установленных Visual Studio 2015.
-
Вы также можете установить его из visualstudiogallery
-
Теперь вы можете легко интегрировать видео и баннерную рекламу в свои приложения.
Microsoft Advertising SDK для универсальных приложений Windows входит в состав библиотек, установленных Visual Studio 2015.
Вы также можете установить его из visualstudiogallery
Теперь вы можете легко интегрировать видео и баннерную рекламу в свои приложения.
Давайте посмотрим на простой пример в XAML, чтобы добавить рекламный баннер в ваше приложение с помощью AdControl .
-
Создайте новый проект универсального пустого приложения Windows с именем UWPBannerAd .
-
В обозревателе решений щелкните правой кнопкой мыши ссылку
Создайте новый проект универсального пустого приложения Windows с именем UWPBannerAd .
В обозревателе решений щелкните правой кнопкой мыши ссылку
-
Выберите Добавить ссылки , чтобы открыть диалоговое окно « Диспетчер ссылок ».
-
На левой панели выберите « Расширения» в разделе «Универсальная Windows» и проверьте Microsoft Advertising SDK для XAML .
Выберите Добавить ссылки , чтобы открыть диалоговое окно « Диспетчер ссылок ».
На левой панели выберите « Расширения» в разделе «Универсальная Windows» и проверьте Microsoft Advertising SDK для XAML .
-
Нажмите OK, чтобы продолжить.
-
Ниже приведен код XAML, в котором AdControl добавлен с некоторыми свойствами.
Нажмите OK, чтобы продолжить.
Ниже приведен код XAML, в котором AdControl добавлен с некоторыми свойствами.
<Page x:Class = "UWPBannerAd.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPBannerAd" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:UI = "using:Microsoft.Advertising.WinRT.UI" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel HorizontalAlignment = "Center"> <UI:AdControl ApplicationId = "d25517cb-12d4-4699-8bdc-52040c712cab" AdUnitId = "10043121" HorizontalAlignment = "Left" Height = "580" VerticalAlignment = "Top" Width = "800"/> </StackPanel> </Grid> </Page>
Когда приведенный выше код скомпилирован и выполнен на локальном компьютере, вы увидите следующее окно с надписью MSN. Когда вы нажмете на этот баннер, он откроет сайт MSN.
Вы также можете добавить видео-баннер в своем приложении. Давайте рассмотрим другой пример, в котором при нажатии кнопки « Показать рекламу» будет воспроизводиться видеообъявление Xbox One.
Ниже приведен код XAML, в котором мы демонстрируем, как кнопка добавляется с некоторыми свойствами и событиями.
<Page x:Class = "UWPBannerAd.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPBannerAd" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:UI = "using:Microsoft.Advertising.WinRT.UI" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel HorizontalAlignment = "Center"> <Button x:Name = "showAd" Content = "Show Ad" HorizontalAlignment = "Left" Margin = "138,296,0,0" VerticalAlignment = "Top" FontSize = "48" Click = "showAd_Click"/> </StackPanel> </Grid> </Page>
Ниже приведена реализация события click в C #.
using Microsoft.Advertising.WinRT.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPBannerAd { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { InterstitialAd videoAd = new InterstitialAd(); public MainPage() { this.InitializeComponent(); } private void showAd_Click(object sender, RoutedEventArgs e) { var MyAppId = "d25517cb-12d4-4699-8bdc-52040c712cab"; var MyAdUnitId = "11388823"; videoAd.AdReady += videoAd_AdReady; videoAd.RequestAd(AdType.Video, MyAppId, MyAdUnitId); } void videoAd_AdReady(object sender, object e){ if ((InterstitialAdState.Ready) == (videoAd.State)) { videoAd.Show(); } } } }
Когда приведенный выше код скомпилирован и выполнен на локальном компьютере, вы увидите следующее окно, в котором есть кнопка « Показать рекламу» .
Теперь, когда вы нажмете кнопку « Показать рекламу» , она будет воспроизводить видео в вашем приложении.
Разработка для Windows 10 – элементы управления XAML
XAML означает расширяемый язык разметки приложений. Это структура пользовательского интерфейса, которая предлагает обширную библиотеку элементов управления, поддерживающих разработку пользовательского интерфейса для Windows. Некоторые из них имеют визуальное представление, например, Button, Textbox, TextBlock и т. Д .; в то время как другие элементы управления используются в качестве контейнеров для других элементов управления или содержимого, такого как изображения и т. д. Все элементы управления XAML наследуются от «System.Windows.Controls.Control» .
XAML Emerging Story
XAML используется во многих важных платформах Microsoft, таких как Windows Presentation Foundation (WPF), Silverlight и, теперь, приложения Windows. Теперь Microsoft Office 2016 также является семейством приложений UWP. XAML – это богатая платформа, которая предоставляет очень интересные функции и элементы управления, которые можно использовать в приложениях UWP.
Полная иерархия наследования элементов управления показана ниже.
Элементы управления макетом
Расположение элементов управления очень важно и критично для удобства использования приложения. Он используется для организации группы элементов GUI в вашем приложении. Есть некоторые важные вещи, которые следует учитывать при выборе панелей макета –
- Позиции дочерних элементов.
- Размеры дочерних элементов.
- Наслаивание перекрывающихся дочерних элементов друг на друга.
Список элементов управления Layout приведен ниже –
S.No. | Управление и описание |
---|---|
1 |
StackPanel StackPanel – это простая и полезная панель макетов в XAML. В панели стека дочерние элементы могут быть расположены в одну линию по горизонтали или по вертикали в зависимости от свойства ориентации. |
2 |
WrapPanel В WrapPanel дочерние элементы располагаются в последовательном порядке слева направо или сверху вниз на основе свойства ориентации. Единственное отличие между StackPanel и WrapPanel состоит в том, что он не укладывает все дочерние элементы в одну строку, а переносит оставшиеся элементы в другую строку, если не осталось места. |
3 |
DockPanel DockPanel определяет область для размещения дочерних элементов относительно друг друга, по горизонтали или по вертикали. С DockPanel вы можете легко закрепить дочерние элементы сверху, снизу, справа, слева и по центру с помощью свойства Dock. С помощью свойства LastChildFill последний дочерний элемент заполняет оставшееся пространство независимо от любого другого значения дока, если оно установлено для этого элемента. |
4 |
холст Холст – это базовая панель макета, в которой дочерние элементы могут быть размещены в явном виде с использованием координат, относящихся к любой стороне, такой как левая, правая, верхняя и нижняя. Обычно Canvas используется для 2D-графических элементов (таких как Ellipse, Rectangle и т. Д.), Но не для элементов пользовательского интерфейса, поскольку при указании абсолютных координат возникают проблемы при изменении размера, локализации или масштабировании в приложении XAML. |
5 |
сетка Сетка обеспечивает гибкую область, которая состоит из строк и столбцов. В Grid дочерние элементы могут быть расположены в табличной форме. Элементы могут быть добавлены в любую конкретную строку и столбец с помощью свойств Grid.Row и Grid.Column . |
6 |
SplitView SplitView представляет контейнер с двумя представлениями; одно представление для основного контента и другое представление, которое обычно используется для команд навигации. |
7 |
RelativePanel RelativePanel определяет область, в которой вы можете позиционировать и выравнивать дочерние объекты относительно друг друга или родительской панели. |
8 |
ViewBox ViewBox определяет декоратор контента, который может растягивать и масштабировать одного дочернего элемента, чтобы заполнить доступное пространство. |
9 |
FlipView FlipView представляет элемент управления элемента, который отображает по одному элементу за раз, и позволяет «перевернуть» поведение для обхода его коллекции элементов. |
10 |
Вид сетки GridView – это элемент управления, который представляет коллекцию элементов в строках и столбцах и может быть прокручен по горизонтали. |
StackPanel
StackPanel – это простая и полезная панель макетов в XAML. В панели стека дочерние элементы могут быть расположены в одну линию по горизонтали или по вертикали в зависимости от свойства ориентации.
WrapPanel
В WrapPanel дочерние элементы располагаются в последовательном порядке слева направо или сверху вниз на основе свойства ориентации. Единственное отличие между StackPanel и WrapPanel состоит в том, что он не укладывает все дочерние элементы в одну строку, а переносит оставшиеся элементы в другую строку, если не осталось места.
DockPanel
DockPanel определяет область для размещения дочерних элементов относительно друг друга, по горизонтали или по вертикали. С DockPanel вы можете легко закрепить дочерние элементы сверху, снизу, справа, слева и по центру с помощью свойства Dock.
С помощью свойства LastChildFill последний дочерний элемент заполняет оставшееся пространство независимо от любого другого значения дока, если оно установлено для этого элемента.
холст
Холст – это базовая панель макета, в которой дочерние элементы могут быть размещены в явном виде с использованием координат, относящихся к любой стороне, такой как левая, правая, верхняя и нижняя. Обычно Canvas используется для 2D-графических элементов (таких как Ellipse, Rectangle и т. Д.), Но не для элементов пользовательского интерфейса, поскольку при указании абсолютных координат возникают проблемы при изменении размера, локализации или масштабировании в приложении XAML.
сетка
Сетка обеспечивает гибкую область, которая состоит из строк и столбцов. В Grid дочерние элементы могут быть расположены в табличной форме. Элементы могут быть добавлены в любую конкретную строку и столбец с помощью свойств Grid.Row и Grid.Column .
SplitView
SplitView представляет контейнер с двумя представлениями; одно представление для основного контента и другое представление, которое обычно используется для команд навигации.
RelativePanel
RelativePanel определяет область, в которой вы можете позиционировать и выравнивать дочерние объекты относительно друг друга или родительской панели.
ViewBox
ViewBox определяет декоратор контента, который может растягивать и масштабировать одного дочернего элемента, чтобы заполнить доступное пространство.
FlipView
FlipView представляет элемент управления элемента, который отображает по одному элементу за раз, и позволяет «перевернуть» поведение для обхода его коллекции элементов.
Вид сетки
GridView – это элемент управления, который представляет коллекцию элементов в строках и столбцах и может быть прокручен по горизонтали.
UI Controls
Вот список элементов управления пользовательского интерфейса, которые видны конечным пользователям.
S.No. | UI Controls & Description |
---|---|
1 |
кнопка Элемент управления, который реагирует на ввод пользователя |
2 |
Календарь Представляет элемент управления, который позволяет пользователю выбирать дату с помощью визуального отображения календаря. |
3 |
CheckBox Элемент управления, который пользователь может выбрать или очистить. |
4 |
Поле со списком Выпадающий список элементов, из которых пользователь может выбрать. |
5 |
Контекстное меню Получает или задает элемент контекстного меню, который должен появляться всякий раз, когда контекстное меню запрашивается через пользовательский интерфейс (UI) из этого элемента. |
6 |
DataGrid Представляет элемент управления, который отображает данные в настраиваемой сетке. |
7 |
DatePicker Элемент управления, который позволяет пользователю выбрать дату. |
8 |
Диалоги Приложение также может отображать дополнительные окна, чтобы пользователь мог собирать или отображать важную информацию. |
9 |
Вылететь Представляет элемент управления, отображающий упрощенный пользовательский интерфейс, который либо является информацией, либо требует взаимодействия с пользователем. В отличие от диалога, всплывающее окно можно легко отклонить, щелкнув или нажав на него снаружи, нажав кнопку «Назад» на устройстве или клавишу «Esc». |
10 |
Образ Элемент управления, который представляет изображение. |
11 |
ListBox Элемент управления, представляющий встроенный список элементов, из которых пользователь может выбирать. |
12 |
меню Представляет элемент управления меню Windows, который позволяет иерархически организовывать элементы, связанные с командами и обработчиками событий. |
13 |
MenuFlyout Представляет всплывающее окно, которое отображает меню команд. |
14 |
PasswordBox Элемент управления для ввода паролей. |
15 |
Неожиданно возникнуть Отображает содержимое поверх существующего содержимого в пределах окна приложения. |
16 |
Индикатор Элемент управления, который показывает прогресс, отображая панель. |
17 |
ProgressRing Элемент управления, который указывает на неопределенный прогресс путем отображения кольца. |
18 |
Переключатель Элемент управления, который позволяет пользователю выбрать один вариант из группы параметров. |
19 |
RichEditBox Элемент управления, позволяющий пользователю редактировать документы в формате RTF с таким содержимым, как форматированный текст, гиперссылки и изображения. |
20 |
ScrollViewer Контейнерный элемент управления, который позволяет пользователю перемещать и масштабировать его содержимое. |
21 |
Поисковая строка Элемент управления, который позволяет пользователю вводить поисковые запросы. |
22 |
ползунок Элемент управления, позволяющий пользователю выбирать из диапазона значений путем перемещения элемента управления Thumb вдоль дорожки. |
23 |
TextBlock Элемент управления, который отображает текст. |
24 |
TimePicker Элемент управления, который позволяет пользователю установить значение времени. |
25 |
Кнопка-переключатель Кнопка, которую можно переключать между двумя состояниями. |
26 |
ToolTip Всплывающее окно, которое отображает информацию для элемента. |
27 |
Окно Корневое окно, которое обеспечивает параметр минимизации / максимизации, строку заголовка, границу и кнопку закрытия. |
кнопка
Элемент управления, который реагирует на ввод пользователя
Календарь
Представляет элемент управления, который позволяет пользователю выбирать дату с помощью визуального отображения календаря.
CheckBox
Элемент управления, который пользователь может выбрать или очистить.
Поле со списком
Выпадающий список элементов, из которых пользователь может выбрать.
Контекстное меню
Получает или задает элемент контекстного меню, который должен появляться всякий раз, когда контекстное меню запрашивается через пользовательский интерфейс (UI) из этого элемента.
DataGrid
Представляет элемент управления, который отображает данные в настраиваемой сетке.
DatePicker
Элемент управления, который позволяет пользователю выбрать дату.
Диалоги
Приложение также может отображать дополнительные окна, чтобы пользователь мог собирать или отображать важную информацию.
Вылететь
Представляет элемент управления, отображающий упрощенный пользовательский интерфейс, который либо является информацией, либо требует взаимодействия с пользователем. В отличие от диалога, всплывающее окно можно легко отклонить, щелкнув или нажав на него снаружи, нажав кнопку «Назад» на устройстве или клавишу «Esc».
Образ
Элемент управления, который представляет изображение.
ListBox
Элемент управления, представляющий встроенный список элементов, из которых пользователь может выбирать.
меню
Представляет элемент управления меню Windows, который позволяет иерархически организовывать элементы, связанные с командами и обработчиками событий.
MenuFlyout
Представляет всплывающее окно, которое отображает меню команд.
PasswordBox
Элемент управления для ввода паролей.
Неожиданно возникнуть
Отображает содержимое поверх существующего содержимого в пределах окна приложения.
Индикатор
Элемент управления, который показывает прогресс, отображая панель.
ProgressRing
Элемент управления, который указывает на неопределенный прогресс путем отображения кольца.
Переключатель
Элемент управления, который позволяет пользователю выбрать один вариант из группы параметров.
RichEditBox
Элемент управления, позволяющий пользователю редактировать документы в формате RTF с таким содержимым, как форматированный текст, гиперссылки и изображения.
ScrollViewer
Контейнерный элемент управления, который позволяет пользователю перемещать и масштабировать его содержимое.
Поисковая строка
Элемент управления, который позволяет пользователю вводить поисковые запросы.
ползунок
Элемент управления, позволяющий пользователю выбирать из диапазона значений путем перемещения элемента управления Thumb вдоль дорожки.
TextBlock
Элемент управления, который отображает текст.
TimePicker
Элемент управления, который позволяет пользователю установить значение времени.
Кнопка-переключатель
Кнопка, которую можно переключать между двумя состояниями.
ToolTip
Всплывающее окно, которое отображает информацию для элемента.
Окно
Корневое окно, которое обеспечивает параметр минимизации / максимизации, строку заголовка, границу и кнопку закрытия.
Ниже приведен пример, который содержит различные типы элементов управления в SplitView . В файле XAML создаются различные элементы управления с некоторыми свойствами и событиями.
<Page x:Class = "UWPControlsDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPControlsDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Margin = "20"> <StackPanel Orientation = "Horizontal"> <ToggleButton x:Name = "HamburgerButton" FontFamily = "Segoe MDL2 Assets" Content = "" Checked = "HandleCheck" Unchecked = "HandleUnchecked" HorizontalAlignment = "Center"/> <AppBarButton Icon = "Like" /> <AppBarButton Icon = "Dislike" /> <AppBarSeparator/> <AppBarButton Icon = "Accept" /> <AppBarButton Icon = "Add" /> </StackPanel> <SplitView x:Name = "splitView" DisplayMode = "Inline" OpenPaneLength = "296"> <SplitView.Pane> <StackPanel> <TextBlock Text = "SplitView Pane" FontSize = "36" VerticalAlignment = "Center" HorizontalAlignment = "Center" Margin = "10"/> <Button Content = "Options" Margin = "10"> <Button.Flyout> <MenuFlyout> <MenuFlyoutItem Text = "Reset"/> <MenuFlyoutSeparator/> <MenuFlyoutItem Text = "Repeat"/> <MenuFlyoutItem Text = "Shuffle"/> </MenuFlyout> </Button.Flyout> </Button> </StackPanel> </SplitView.Pane> <StackPanel> <TextBlock Text = "SplitView Content" FontSize = "36" VerticalAlignment = "Center" HorizontalAlignment = "Center" Margin = "10"/> <Border BorderThickness = "3" BorderBrush = "Red" Margin = "5"> <StackPanel Orientation = "Horizontal"> <TextBlock Text = "Hyperlink example" Margin = "5"/> <HyperlinkButton Content = "www.microsoft.com" NavigateUri = "http://www.microsoft.com"/> </StackPanel> </Border> <RelativePanel BorderBrush = "Red" BorderThickness = "2" CornerRadius = "10" Padding = "12" Margin = "5"> <TextBlock x:Name = "txt" Text = "Relative Panel example" RelativePanel.AlignLeftWithPanel = "True" Margin = "5,0,0,0"/> <TextBox x:Name = "textBox1" RelativePanel.RightOf = "btn" Margin = "5,0,0,0"/> <Button x:Name = "btn" Content = "Name" RelativePanel.RightOf = "txt" Margin = "5,0,0,0"/> </RelativePanel> <FlipView Height = "400" Margin = "10" Width = "400"> <Image Source = "Images/DSC_0104.JPG"/> <Image Source = "Images/DSC_0080.JPG"/> <Image Source = "Images/DSC_0076.JPG"/> <Image Source = "Images/thGTF7BWGW.jpg"/> </FlipView> </StackPanel> </SplitView> </StackPanel> </Grid> </Page>
Ниже приведена реализация Events в C #.
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPControlsDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void HandleCheck(object sender, RoutedEventArgs e) { splitView.IsPaneOpen = true; } private void HandleUnchecked(object sender, RoutedEventArgs e) { splitView.IsPaneOpen = false; } } }
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно –
Когда вы нажимаете кнопку гамбургера в верхней левой части, она открывает / закрывает панель SplitView .
На панели SplitView вы можете видеть элементы управления Flyout , MenuFlyout и FlipView .
В содержимом SplitView вы можете видеть гиперссылку, относительную панель, ViewBox и другие кнопки и элементы управления текстовым полем.
Разработка для Windows 10 – привязка данных
Привязка данных – это механизм в приложении XAML, который обеспечивает простой и легкий способ для приложений среды выполнения Windows, использующих частичные классы для отображения и взаимодействия с данными. Управление данными полностью отделено от способа отображения данных в этом механизме.
Привязка данных обеспечивает поток данных между элементами пользовательского интерфейса и объектом данных в пользовательском интерфейсе. Когда привязка установлена и данные или ваша бизнес-модель изменяются, она автоматически отражает обновления элементов пользовательского интерфейса и наоборот. Также возможно связать не со стандартным источником данных, а с другим элементом на странице. Привязка данных может быть –
- Односторонняя привязка данных
- Двусторонняя привязка данных
- Привязка элемента
Одностороннее связывание данных
При одностороннем связывании данные привязываются от своего источника (объекта, который содержит данные) к своей цели (объекту, который отображает данные).
Давайте посмотрим на простой пример односторонней привязки данных. Ниже приведен код XAML, в котором создаются четыре текстовых блока с некоторыми свойствами.
<Page x:Class = "OneWayDataBinding.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:OneWayDataBinding" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Name = "Display"> <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0"> <TextBlock Text = "Name: " Margin = "10" Width = "100"/> <TextBlock Margin = "10" Width = "100" Text = "{Binding Name}"/> </StackPanel> <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0"> <TextBlock Text = "Title: " Margin = "10" Width = "100"/> <TextBlock Margin = "10" Width = "200" Text = "{Binding Title}" /> </StackPanel> </StackPanel> </Grid> </Page>
Свойства текста двух текстовых блоков статически установлены на «Имя» и «Заголовок» , тогда как два других свойства текста текстовых блоков привязаны к «Имя» и «Заголовок», которые являются переменными класса класса Employee, как показано ниже.
using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace OneWayDataBinding { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage(){ this.InitializeComponent(); DataContext = Employee.GetEmployee(); } } public class Employee { public string Name { get; set; } public string Title { get; set; } public static Employee GetEmployee() { var emp = new Employee() { Name = "Waqar Ahmed", Title = "Development Manager" }; return emp; } } }
В классе Employee у нас есть переменные Name и Title и один статический метод, в котором объект employee инициализируется и возвращает этот объект employee. Следовательно, мы привязываемся к свойству Name и Title, но еще не выбрали объект, к которому относится это свойство. Самый простой способ – назначить объект DataContext , свойства которого мы связываем в конструкторе MainPage .
Когда вы запустите это приложение, вы сразу увидите в главном окне, что вы успешно связали имя и заголовок этого объекта Employee.
Двухстороннее связывание данных
В двустороннем связывании пользователь может изменять данные через пользовательский интерфейс и обновлять эти данные в источнике. Например, если источник изменяется, когда пользователь просматривает представление, необходимо обновить представление.
Давайте посмотрим на приведенный ниже пример, в котором созданы две метки, два текстовых поля и одна кнопка с некоторыми свойствами и событиями.
<Page x:Class = "TwoWayDataBinding.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:TwoWayDataBinding" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height = "Auto" /> <RowDefinition Height = "Auto" /> <RowDefinition Height = "*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width = "Auto" /> <ColumnDefinition Width = "200" /> </Grid.ColumnDefinitions> <TextBlock Name = "nameLabel" Margin = "200,20,0,0">Name:</TextBlock> <TextBox Name = "nameText" Grid.Column = "1" Margin = "10,20,0,0" Text = "{Binding Name, Mode = TwoWay}"/> <TextBlock Name = "ageLabel" Margin = "200,20,0,0" Grid.Row = "1">Age:</TextBlock> <TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "10,20,0,0" Text = "{Binding Age, Mode = TwoWay}"/> <StackPanel Grid.Row = "2" Grid.ColumnSpan = "2"> <Button Content = "Display" Click = "Button_Click" Margin = "200,20,0,0"/> <TextBlock x:Name = "txtblock" Margin = "200,20,0,0"/> </StackPanel> </Grid> </Page>
Мы можем наблюдать следующее –
-
Свойства Text обоих текстовых полей привязываются к «Name» и «Age», которые являются переменными класса Person, как показано ниже.
-
В классе Person у нас есть только две переменные – Name и Age, и его объект инициализируется в классе MainWindow .
-
В коде XAML мы привязываем свойство – Name и Age , но мы не выбрали объект, которому принадлежит свойство.
-
Более простой способ – присвоить объект DataContext , свойства которого мы связываем в коде C #, как показано ниже в MainWindowconstructor .
Свойства Text обоих текстовых полей привязываются к «Name» и «Age», которые являются переменными класса Person, как показано ниже.
В классе Person у нас есть только две переменные – Name и Age, и его объект инициализируется в классе MainWindow .
В коде XAML мы привязываем свойство – Name и Age , но мы не выбрали объект, которому принадлежит свойство.
Более простой способ – присвоить объект DataContext , свойства которого мы связываем в коде C #, как показано ниже в MainWindowconstructor .
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace TwoWayDataBinding { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { Person person = new Person { Name = "Salman", Age = 26 }; public MainPage() { this.InitializeComponent(); this.DataContext = person; } private void Button_Click(object sender, RoutedEventArgs e) { string message = person.Name + " is " + person.Age + " years old"; txtblock.Text = message; } } public class Person { private string nameValue; public string Name { get { return nameValue; } set { nameValue = value; } } private double ageValue; public double Age { get { return ageValue; } set { if (value != ageValue) { ageValue = value; } } } } }
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно. Нажмите кнопку Показать .
Давайте изменим Имя и Возраст и снова нажмите кнопку Показать .
Вы можете видеть, что при нажатии кнопки «Показать» текст текстовых полей не используется для отображения данных в TextBlock, а используются переменные класса.
Я рекомендую вам выполнить приведенный выше код в обоих случаях для лучшего понимания.
Привязка элемента
Также возможно связать не со стандартным источником данных, а с другим элементом на странице. Давайте создадим приложение под названием ElementBinding, в котором создаются ползунок и прямоугольник, а ползунок ограничивает ширину и высоту прямоугольника. Ниже приведен код в XAML.
<Page x:Class = "ElementBinding.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:ElementBinding" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel VerticalAlignment = "Center" HorizontalAlignment = "Center"> <Rectangle Height = "100" Width = "100" Fill = "SteelBlue" RenderTransformOrigin = "0.5,0.5" Margin = "50"> <Rectangle.RenderTransform> <CompositeTransform ScaleX = "{Binding Value, ElementName = MySlider}" ScaleY = "{Binding Value, ElementName = MySlider}"/> </Rectangle.RenderTransform> </Rectangle> <Slider Minimum = ".5" Maximum = "2.0" StepFrequency = ".1" x:Name = "MySlider" /> </StackPanel> </Grid> </Page>
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
С помощью ползунка вы можете изменить размер прямоугольника, как показано ниже.
Windows 10 Dev – производительность XAML
Производительность приложений, например, как быстро ваше приложение появляется при запуске или перемещается для отображения следующего контента и т. Д., Очень важно.
На производительность приложения могут влиять многие факторы, включая способность механизма рендеринга XAML анализировать весь код XAML, который имеется в вашем приложении. XAML – очень мощный инструмент для создания пользовательского интерфейса, но он может быть более надежным благодаря использованию новых методов, которые теперь доступны в приложениях Windows 10.
Например, в ваших приложениях есть определенные вещи, которые вы хотите показать при загрузке страницы, а потом они не понадобятся позже. Также возможно, что при запуске вам не нужно загружать все элементы пользовательского интерфейса.
В приложениях Windows 10 в XAML добавлены некоторые новые функции, которые улучшили производительность XAML.
Производительность любого универсального приложения Windows можно улучшить с помощью следующих методов;
- Прогрессивный рендеринг
- Отложенная загрузка
Прогрессивный рендеринг
В Windows 10 две новые и очень интересные функции представлены в XAML. Они –
х: Bind
Это новый синтаксис, введенный в XAML, используемый для привязки, который работает почти так же, как синтаксис Binding . х: связывание имеет два ключевых различия; это обеспечивает проверку синтаксиса во время компиляции и лучшую производительность.
X: Фаза
Он предоставляет возможность приоритезировать рендеринг элементов управления XAML в шаблоне данных. Каждый элемент пользовательского интерфейса может иметь только одну указанную фазу. Если это так, это будет применяться ко всем привязкам элемента. Если фаза не указана, фаза 0 предполагается.
В приложениях универсальной платформы Windows (UWP) эти две новые функции обеспечивают повышение производительности. Его также можно использовать в существующих приложениях Windows 8.x, которые переносятся на Windows 10.
Ниже приведен пример, в котором объекты сотрудников связаны с GridView с помощью ключевого слова x: Bind .
<Page x:Class = "XAMLPhase.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:XAMLPhase" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <GridView Name = "Presidents" ItemsSource = "{Binding}" Height = "300" Width = "400" Margin = "50"> <GridView.ItemTemplate> <DataTemplate x:DataType = "local:Employee"> <StackPanel Orientation = "Horizontal" Margin = "2"> <TextBlock Text = "{x:Bind Name}" Width = "95" Margin = "2" /> <TextBlock Text = "{x:Bind Title}" Width = "95" Margin = "2" x:Phase = "1"/> </StackPanel> </DataTemplate> </GridView.ItemTemplate> </GridView> </Grid> </Page>
В приведенном выше коде XAML x: Phase = “1” определено с заголовком. Следовательно, на первом этапе будет отображаться Имя , а затем – Название .
Ниже приведена реализация класса Employee в C #.
using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace XAMLPhase { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); DataContext = Employee.GetEmployees(); } } public class Employee : INotifyPropertyChanged { private string name; public string Name { get { return name; } set { name = value; RaiseProperChanged(); } } private string title; public string Title { get { return title; } set { title = value; RaiseProperChanged(); } } public static Employee GetEmployee() { var emp = new Employee() { Name = "Waqas", Title = "Software Engineer" }; return emp; } public event PropertyChangedEventHandler PropertyChanged; private void RaiseProperChanged( [CallerMemberName] string caller = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(caller)); } } public static ObservableCollection<Employee> GetEmployees() { var employees = new ObservableCollection<Employee>(); employees.Add(new Employee() { Name = "Ali", Title = "Developer" }); employees.Add(new Employee() { Name = "Ahmed", Title = "Programmer" }); employees.Add(new Employee() { Name = "Amjad", Title = "Desiner" }); employees.Add(new Employee() { Name = "Waqas", Title = "Programmer" }); employees.Add(new Employee() { Name = "Bilal", Title = "Engineer" }); employees.Add(new Employee() { Name = "Waqar", Title = "Manager" }); return employees; } } }
Когда приведенный выше код будет выполнен, вы увидите следующее окно.
X: Phase with x: Bind используется для постепенной визуализации элементов ListView и GridView и улучшения процесса панорамирования.
Отложенная загрузка
Отложенная загрузка – это метод, который можно использовать для минимизации времени загрузки при запуске путем уменьшения количества элементов пользовательского интерфейса XAML при запуске приложения. Если ваше приложение содержит 30 элементов пользовательского интерфейса, и пользователю не нужны все эти элементы при запуске, все те элементы, которые не требуются, могут сэкономить некоторое время загрузки путем отсрочки.
x: DeferLoadStrategy = “Lazy” задерживает создание элемента и его дочерних элементов, что уменьшает время запуска, но немного увеличивает использование памяти.
Отложенный элемент может быть реализован / создан путем вызова FindName с именем, которое было определено для элемента.
После создания отложенного элемента произойдет несколько вещей:
-
Событие Loaded для элемента будет вызвано.
-
Любые привязки к элементу будут оценены.
-
Если приложение зарегистрировано для получения уведомлений об изменении свойства для свойства, содержащего отложенный элемент (элементы), уведомление будет поднято.
Событие Loaded для элемента будет вызвано.
Любые привязки к элементу будут оценены.
Если приложение зарегистрировано для получения уведомлений об изменении свойства для свойства, содержащего отложенный элемент (элементы), уведомление будет поднято.
Ниже приведен пример, в котором x: DeferLoadStrategy = “Lazy” используется для сетки, которая содержит четыре текстовых блока и не будет загружаться при запуске вашего приложения, пока вы не загрузите его.
<Page x:Class = "UWPDeferredLoading.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPDeferredLoading" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid x:Name = "DeferredGrid" x:DeferLoadStrategy = "Lazy" Margin = "50"> <Grid.RowDefinitions> <RowDefinition Height = "Auto" /> <RowDefinition Height = "Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width = "Auto" /> <ColumnDefinition Width = "Auto" /> </Grid.ColumnDefinitions> <TextBlock Height = "100" Width = "100" Text = "TextBlock 1" Margin = "0,0,4,4" /> <TextBlock Height = "100" Width = "100" Text = "TextBlock 2" Grid.Column = "1" Margin = "4,0,0,4" /> <TextBlock Height = "100" Width = "100" Text = "TextBlock 3" Grid.Row = "1" Margin = "0,4,4,0" /> <TextBlock Height = "100" Width = "100" Text = "TextBlock 4" Grid.Row = "1" Grid.Column = "1" Margin = "4,4,0,0" /> </Grid> <Button x:Name = "RealizeElements" Content = "Show Elements" Click = "RealizeElements_Click" Margin = "50"/> </Grid> </Page>
Следующая программа представляет собой реализацию события щелчка, в которой сетка загружается на главную страницу приложения.
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPDeferredLoading { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void RealizeElements_Click(object sender, RoutedEventArgs e) { this.FindName("DeferredGrid"); // This will realize the deferred grid } } }
Когда приведенный выше код соблюдается и выполняется, вы увидите только кнопку. Текстовые блоки не загружаются при запуске.
Теперь, когда вы нажмете кнопку « Показать элементы» , она загрузит текстовые блоки, что улучшит производительность вашего приложения при запуске.
Разработка Windows 10 – Адаптивный дизайн
В Windows 10 приложения универсальной платформы Windows (UWP) теперь будут работать на ряде семейств устройств, таких как –
-
Семейство настольных устройств – планшеты, ноутбуки, ПК
-
Семейство мобильных устройств – телефоны Windows, фаблеты
-
Семейство устройств IoT – компактные устройства, такие как носимые или бытовые приборы
-
Семейство командных устройств – Surface Hub
Семейство настольных устройств – планшеты, ноутбуки, ПК
Семейство мобильных устройств – телефоны Windows, фаблеты
Семейство устройств IoT – компактные устройства, такие как носимые или бытовые приборы
Семейство командных устройств – Surface Hub
Каждое семейство устройств имеет свой собственный экран и размер окна. Итак, как спроектировать приложение, которое обеспечивает отличное взаимодействие с пользователем на нескольких устройствах с совершенно разными размерами экрана и разными методами ввода?
Разработка приложения для нескольких семейств устройств требует дополнительного рассмотрения, планирования и проектирования. Windows 10 UWP предоставляет набор встроенных функций и универсальных строительных блоков, которые значительно упрощают проектирование для нескольких устройств и автоматически масштабируются по разным размерам экрана и окна, поддерживаемым элементами управления платформы.
Новые встроенные функции
Ниже приведены новые функции, которые разработчики могут использовать при создании приложения UWP. Эти функции являются автоматическими и бесплатными.
Эффективные пиксели и масштабирование платформы
Когда ваше приложение UWP работает на любом устройстве, поддерживаемом Windows 10, тогда –
-
Система использует алгоритм для нормализации способа отображения элементов управления, шрифтов и других элементов пользовательского интерфейса на экране устройства, на котором оно в данный момент работает.
-
Алгоритм масштабирования управляет расстоянием просмотра и плотностью экрана (пикселей на дюйм) для оптимизации предполагаемого размера (а не физического размера).
-
Алгоритм масштабирования гарантирует, что шрифт 36 px на Surface Hub на расстоянии 10 футов от пользователя будет так же удобен для чтения, как шрифт 36 px на 5-дюймовом телефоне, который находится на расстоянии нескольких дюймов.
Система использует алгоритм для нормализации способа отображения элементов управления, шрифтов и других элементов пользовательского интерфейса на экране устройства, на котором оно в данный момент работает.
Алгоритм масштабирования управляет расстоянием просмотра и плотностью экрана (пикселей на дюйм) для оптимизации предполагаемого размера (а не физического размера).
Алгоритм масштабирования гарантирует, что шрифт 36 px на Surface Hub на расстоянии 10 футов от пользователя будет так же удобен для чтения, как шрифт 36 px на 5-дюймовом телефоне, который находится на расстоянии нескольких дюймов.
Универсальный ввод и интеллектуальные взаимодействия
Универсальная платформа Windows имеет встроенные интеллектуальные системы ввода взаимодействий, которые понимают ввод для всех устройств. Например, когда вы разрабатываете взаимодействие по щелчку в приложении, вам не нужно знать, происходит ли щелчок по фактическому щелчку мыши или касанию пальцем. Система сделает это автоматически для вас.
Универсальные Строительные Блоки
Есть несколько ценных строительных блоков, которые упрощают разработку приложений для нескольких семейств устройств в универсальной платформе Windows (UWP).
Универсальные органы управления
UWP предоставляет набор универсальных элементов управления, которые гарантированно будут работать на всех устройствах Windows 10.
-
Этот список «Универсальные элементы управления» содержит общие элементы управления, такие как переключатель, комбинированный список, текстовое поле и т. Д.
-
Он также содержит некоторые сложные элементы управления, такие как представление сетки и представление списка, которые могут генерировать список элементов из потока данных и шаблона.
Этот список «Универсальные элементы управления» содержит общие элементы управления, такие как переключатель, комбинированный список, текстовое поле и т. Д.
Он также содержит некоторые сложные элементы управления, такие как представление сетки и представление списка, которые могут генерировать список элементов из потока данных и шаблона.
Универсальные стили
Приложение UWP автоматически получает набор стилей по умолчанию, который предоставляет вам эти функции –
-
Набор стилей, которые автоматически придают вашему приложению светлую или темную тему.
-
Анимации по умолчанию для взаимодействий.
-
Автоматическая поддержка высококонтрастных режимов.
-
Автоматическая поддержка других языков. Наши стили по умолчанию автоматически выбирают правильный шрифт для каждого языка, который поддерживает Windows. Вы даже можете использовать несколько языков в одном приложении, и они будут отображаться правильно.
Набор стилей, которые автоматически придают вашему приложению светлую или темную тему.
Анимации по умолчанию для взаимодействий.
Автоматическая поддержка высококонтрастных режимов.
Автоматическая поддержка других языков. Наши стили по умолчанию автоматически выбирают правильный шрифт для каждого языка, который поддерживает Windows. Вы даже можете использовать несколько языков в одном приложении, и они будут отображаться правильно.
Разработка для Windows 10 – адаптивный интерфейс
Приложение универсальной платформы Windows (UWP) может работать на разных устройствах, и каждое устройство имеет свою собственную форму ввода, разрешение экрана, плотность DPI и другие уникальные характеристики.
В Windows 10 с помощью новых универсальных элементов управления, панелей и инструментов вы можете легко адаптировать свой пользовательский интерфейс к устройствам, на которых может работать ваше приложение. Например, когда ваше приложение UWP работает на настольном компьютере, мобильном устройстве или планшете, вы можете настроить пользовательский интерфейс, чтобы использовать различные разрешения экрана, размеры экрана и плотность DPI.
В Windows 10 вы можете легко настроить свой пользовательский интерфейс на несколько устройств с помощью следующих функций:
-
Вы можете улучшить свой пользовательский интерфейс для разных разрешений экрана и размеров экрана, используя универсальные элементы управления и панели макета.
-
Общая обработка ввода позволяет получать ввод через сенсорную панель, ручку, мышь, клавиатуру или контроллер, такой как контроллер Microsoft Xbox.
-
С помощью Инструментов вы можете создать пользовательский интерфейс своего приложения, который может адаптироваться к различным разрешениям экрана.
-
Адаптивное масштабирование подстраивается под разрешение и разницу DPI на разных устройствах.
Вы можете улучшить свой пользовательский интерфейс для разных разрешений экрана и размеров экрана, используя универсальные элементы управления и панели макета.
Общая обработка ввода позволяет получать ввод через сенсорную панель, ручку, мышь, клавиатуру или контроллер, такой как контроллер Microsoft Xbox.
С помощью Инструментов вы можете создать пользовательский интерфейс своего приложения, который может адаптироваться к различным разрешениям экрана.
Адаптивное масштабирование подстраивается под разрешение и разницу DPI на разных устройствах.
В Windows 10 вы можете легко упорядочивать, изменять размеры и размещать приложения любым удобным для вас способом. Это также дает пользователю некоторую гибкость в использовании вашего приложения так, как он хочет. В Windows 10 существуют различные способы реализации адаптивных методов в вашем приложении UWP, поэтому оно отлично выглядит независимо от размера экрана или окна.
VisualStateManager
В Windows 10 класс VisualStateManager имеет два новых механизма, с помощью которых вы можете реализовать адаптивный дизайн в ваших приложениях UWP. Новый VisualState.StateTriggers позволяет разработчику проверять определенные условия, такие как высота окна или ширина окна, а затем API-интерфейсы VisualState.Setters определяют визуальные состояния в ответ на эти определенные условия.
Давайте посмотрим на приведенный ниже пример, в котором некоторые элементы управления добавлены в панель стека.
<Page x:Class = "UWPAdaptiveUI.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPAdaptiveUI" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState> <VisualState.StateTriggers> <!-- VisualState to be triggered when window width is >=720 effective pixels. --> <AdaptiveTrigger MinWindowWidth = "720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target = "myPanel.Orientation" Value = "Horizontal" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <StackPanel x:Name = "myPanel" Orientation = "Vertical"> <TextBlock Text = "Windows 10 Tutorials: Text block 1. " Style = "{ThemeResource BodyTextBlockStyle}"/> <TextBlock Text = "Windows 10 Tutorials: Text block 2. " Style = "{ThemeResource BodyTextBlockStyle}"/> <TextBlock Text = "Windows 10 Tutorials: Text block 3. " Style = "{ThemeResource BodyTextBlockStyle}"/> </StackPanel> </Grid> </Page>
Теперь VisualStateManager отрегулирует ориентацию панели стека в зависимости от ширины окна. Если ширина> = 720, то ориентация станет горизонтальной, в противном случае она останется вертикальной. Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно, которое содержит три текстовых блока в вертикальном порядке.
Давайте изменим ширину вышеупомянутого окна, и вы увидите следующее окно –
Теперь вы можете видеть, что текстовые блоки расположены в горизонтальном порядке.
RelativePanel
RelativePanel может использоваться для разметки элементов пользовательского интерфейса путем выражения пространственных отношений между элементами. Давайте возьмем пример, в котором некоторые прямоугольники создаются в соответствующей панели.
<Page x:Class = "UWPAdaptiveUI.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPAdaptiveUI" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth = "720" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target = "GreenRect.(RelativePanel.RightOf)" Value = "BlueRect" /> <Setter Target = "GreenRect.(RelativePanel.AlignRightWithPanel)" Value = "True" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <RelativePanel BorderBrush = "Gray" BorderThickness = "10"> <Rectangle x:Name = "RedRect" Fill = "Red" MinHeight = "100" MinWidth = "100"/> <Rectangle x:Name = "BlueRect" Fill = "Blue" MinHeight = "100" MinWidth = "100" RelativePanel.RightOf = "RedRect" /> <!-- Width is not set on the green and yellow rectangles. It's determined by the RelativePanel properties. --> <Rectangle x:Name = "GreenRect" Fill = "Green" MinHeight = "100" RelativePanel.Below = "BlueRect" RelativePanel.AlignLeftWith = "RedRect" RelativePanel.AlignRightWith = "BlueRect"/> <Rectangle Fill = "Yellow" MinHeight = "100" RelativePanel.Below = "GreenRect" RelativePanel.AlignLeftWith = "BlueRect" RelativePanel.AlignRightWithPanel = "True"/> </RelativePanel> </Grid> </Page>
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
Когда вы измените размер окна выше, вы увидите, что зеленый прямоугольник теперь корректируется в верхнем ряду слева от синего прямоугольника, как показано ниже.
Разработка для Windows 10 – Адаптивный код
В этой главе мы продемонстрируем адаптацию вашего приложения к различным устройствам, поддерживаемым Windows 10. Мы уже узнали о принятии вашего пользовательского интерфейса и всех приемах, методах и элементах управления, используемых в приложениях UWP.
Теперь мы узнаем о принятии вашего кода, потому что
-
Коды приложений не одинаковы для всех устройств.
-
Используемые API, особенно для Xbox, не будут доступны для мобильных устройств. То же самое относится и к HoloLens и т. Д.
Коды приложений не одинаковы для всех устройств.
Используемые API, особенно для Xbox, не будут доступны для мобильных устройств. То же самое относится и к HoloLens и т. Д.
Адаптивный код может условно освещать ваше приложение и выполнять код только при запуске на определенном семействе устройств и / или на определенной версии API-интерфейсов платформы / расширения.
Написание кода
В Windows 10 вы можете реализовать приложения UWP в Visual Studio, используя C ++, C #, Visual Basic или JavaScript.
-
С C # и Visual Basic вы можете использовать XAML для проектирования пользовательского интерфейса.
-
С C ++ вы можете использовать DirectX вместо XAML.
-
Для JavaScript вы можете использовать HTML для уровня презентации, который является кросс-платформенным веб-стандартом.
С C # и Visual Basic вы можете использовать XAML для проектирования пользовательского интерфейса.
С C ++ вы можете использовать DirectX вместо XAML.
Для JavaScript вы можете использовать HTML для уровня презентации, который является кросс-платформенным веб-стандартом.
Windows Core API работают одинаково для всех устройств, которые содержат большую часть функциональности, необходимой для вашего кода и пользовательского интерфейса. Однако для кода и пользовательского интерфейса, предназначенных для определенных семейств устройств, необходимо использовать адаптивный код и адаптивный пользовательский интерфейс.
Вызов API, который НЕ реализован целевым семейством устройств –
Пользовательский интерфейс легко адаптируется к различным экранам, но разные семейства устройств не только имеют разные размеры экрана, но и намного больше.
-
Например, на мобильных телефонах есть некоторые аппаратные кнопки, такие как «Назад» и «Камера», которые могут быть недоступны на других устройствах, таких как ПК.
-
По умолчанию основные API-интерфейсы содержат большую часть функциональности, которая работает для всех устройств, но специальные функциональные возможности устройства можно использовать, ссылаясь на SDK-расширения в ваших приложениях UWP, как внешние сборки.
Например, на мобильных телефонах есть некоторые аппаратные кнопки, такие как «Назад» и «Камера», которые могут быть недоступны на других устройствах, таких как ПК.
По умолчанию основные API-интерфейсы содержат большую часть функциональности, которая работает для всех устройств, но специальные функциональные возможности устройства можно использовать, ссылаясь на SDK-расширения в ваших приложениях UWP, как внешние сборки.
Чтобы добавить какой-либо конкретный SDK расширения, необходимый в вашем приложении, выполните следующие действия:
-
Щелкните правой кнопкой мыши на References .
-
Выберите «Добавить ссылки ..» . Следующий диалог откроется.
Щелкните правой кнопкой мыши на References .
Выберите «Добавить ссылки ..» . Следующий диалог откроется.
-
Добавить расширение так же просто, как добавить ссылку на проект.
-
Теперь вы можете добавить любое расширение SDK из списка, который содержит расширение Desktop, расширение IoT, расширение Mobile и т. Д.
Добавить расширение так же просто, как добавить ссылку на проект.
Теперь вы можете добавить любое расширение SDK из списка, который содержит расширение Desktop, расширение IoT, расширение Mobile и т. Д.
Настольные и мобильные расширения – это два наиболее распространенных SDK расширения платформы. Например, расширение Mobile позволяет API-интерфейсам, необходимым для использования кнопки аппаратной камеры.
Вы можете проверить возможности устройства с помощью метода класса Windows.Foundation.Metadata.ApiInformation , который возвращает логический вывод, если тип поддерживается на текущем устройстве. Например, вы можете разрешить вашему приложению Windows использовать кнопку «Камера» с таким кодом:
bool isHardwareButtonsAPIPresent = Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.Phone.UI.Inpu t.HardwareButtons"); if (isHardwareButtonsAPIPresent) { Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed; }
Код кнопки телефона и камеры будет выполняться только в том случае, если на устройстве включен Mobile Extension SDK. Аналогично, вы также можете проверить наличие какого-либо конкретного события, метода или свойства в текущей версии API, используя IsEventPresent , IsMethodPresent , IsPropertyPresent вместо IsTypePresent, как показано ниже.
bool isHardwareButtons_CameraPressedAPIPresent = Windows.Foundation.Metadata.ApiInformation.IsEventPresent ("Windows.Phone.UI.Input.HardwareButtons", "CameraPressed");
Win32 API в UWP
Приложение универсальной платформы вдов (UWP) или компонент среды выполнения Windows, написанные на C ++ / CX, могут получать доступ к API-интерфейсам Win32, которые также являются частью UWP. Все семейства устройств Windows 10 могут реализовывать Win32 API, связывая ваше приложение с Windowsapp.lib .
Windowsapp.lib является «зонтичной» библиотекой, которая обеспечивает экспорт для API UWP. Ссылка на Windowsapp.lib добавит к вашему приложению зависимости от dll , которые присутствуют на всех семействах устройств Windows 10.
Давайте рассмотрим простой пример, в котором приложение предназначено как для настольного компьютера, так и для телефона. Поэтому, когда приложение запускается на рабочем столе, оно не отображает строку состояния, но когда то же приложение запускается на телефоне, оно отображает строку состояния.
Ниже приведен код XAML, в который добавлены различные элементы управления.
<Page x:Class = "UWPAdoptiveCode.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPAdoptiveCode" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Page.Background> <SolidColorBrush Color = "Green"/> </Page.Background> <Page.BottomAppBar> <CommandBar x:Name = "commandBar" > <AppBarButton Icon = "Accept" Label = "appbarbutton"/> <AppBarButton Icon = "Cancel" Label = "appbarbutton"/> </CommandBar> </Page.BottomAppBar> <Grid Background = "AliceBlue"> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState> <VisualState.StateTriggers> <local:DeviceFamilyTrigger DeviceFamily = "Desktop" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target = "StatusBarControls.Visibility" Value = "Collapsed"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <StackPanel HorizontalAlignment = "Left" Margin = "75,164,0,0" VerticalAlignment = "Top" > <RadioButton x:Name = "ShowAppBarRadioButton" Content = "Show AppBar" HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" IsChecked = "True" Checked = "RadioButton_Checked"/> <RadioButton x:Name = "ShowOpaqueAppBarRadioButton" Content = "Show Transparent AppBar" HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" Checked = "RadioButton_Checked"/> <RadioButton x:Name = "HideAppBarRadioButton" Content = "Hide AppBar" HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" Checked = "RadioButton_Checked"/> </StackPanel> <StackPanel x:Name = "StatusBarControls" Orientation = "Vertical" Margin = "75,350,0,0" Visibility = "Visible"> <CheckBox x:Name = "StatusBarBackgroundCheckBox" Content = "Set StatusBar Background" Checked = "StatusBarBackgroundCheckBox_Checked" Unchecked = "StatusBarBackgroundCheckBox_Unchecked"/> <CheckBox x:Name = "StatusBarHiddenCheckBox" Content = "Set StatusBar Hidden" Checked = "StatusBarHiddenCheckBox_Checked" Unchecked = "StatusBarHiddenCheckBox_Unchecked"/> </StackPanel> </Grid> </Page>
Ниже приведена реализация C # для различных событий.
using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPAdoptiveCode { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { private Color? DefaultTitleBarButtonsBGColor; private Color? DefaultTitleBarBGColor; public MainPage() { this.InitializeComponent(); //Windows.UI.ViewManagement.ApplicationView.GetForCurrentView(). VisibleBoundsCh anged += MainPage_VisibleBoundsChanged; var viewTitleBar = Windows.UI.ViewManagement.ApplicationView. GetForCurrentView().TitleBar; DefaultTitleBarBGColor = viewTitleBar.BackgroundColor; DefaultTitleBarButtonsBGColor = viewTitleBar.ButtonBackgroundColor; } private void RadioButton_Checked(object sender, RoutedEventArgs e) { // Bottom AppBar shows on Desktop and Mobile if (ShowAppBarRadioButton != null) { if (ShowAppBarRadioButton.IsChecked.HasValue && (ShowAppBarRadioButton.IsChecked.Value == true)) { commandBar.Visibility = Windows.UI.Xaml.Visibility.Visible; commandBar.Opacity = 1; } else { commandBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } } if (ShowOpaqueAppBarRadioButton != null) { if (ShowOpaqueAppBarRadioButton.IsChecked.HasValue && (ShowOpaqueAppBarRadioButton.IsChecked.Value == true)){ commandBar.Visibility = Windows.UI.Xaml.Visibility.Visible; commandBar.Background.Opacity = 0; } else{ commandBar.Background.Opacity = 1; } } } private void StatusBarHiddenCheckBox_Checked(object sender, RoutedEventArgs e){ // StatusBar is Mobile only if (Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ var ignore = Windows.UI.ViewManagement.StatusBar.GetForCurrentView().HideAsync(); } } private void StatusBarHiddenCheckBox_Unchecked(object sender, RoutedEventArgs e){ // StatusBar is Mobile only if (Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ var ignore = Windows.UI.ViewManagement.StatusBar.GetForCurrentView().ShowAsync(); } } private void StatusBarBackgroundCheckBox_Checked(object sender, RoutedEventArgs e){ // StatusBar is Mobile only if (Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ Windows.UI.ViewManagement.StatusBar.GetForCurrentView(). BackgroundColor = Windows.UI.Colors.Blue; Windows.UI.ViewManagement.StatusBar.GetForCurrentView(). BackgroundOpacity = 1; } } private void StatusBarBackgroundCheckBox_Unchecked(object sender, RoutedEventArgs e){ // StatusBar is Mobile only if (Windows.Foundation.Metadata.ApiInformation. IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ Windows.UI.ViewManagement.StatusBar.GetForCurrentView(). BackgroundOpacity = 0; } } } public class DeviceFamilyTrigger : StateTriggerBase{ //private variables private string _deviceFamily; //Public property public string DeviceFamily { get { return _deviceFamily; } set{ _deviceFamily = value; var qualifiers = Windows.ApplicationModel.Resources.Core.ResourceContext. GetForCurrentView().Qua lifierValues; if (qualifiers.ContainsKey("DeviceFamily")) SetActive(qualifiers["DeviceFamily"] == _deviceFamily); else SetActive(false); } } } }
Когда приведенный выше код скомпилирован и выполнен на мобильном телефоне, вы увидите следующее окно.
Вы можете изменить цвет фона строки состояния с помощью флажка, как показано на рисунке.
Вы также можете скрыть строку состояния.
Теперь, когда вы запустите одно и то же приложение на настольном устройстве, вы увидите следующее окно, в котором строка состояния и флажки, относящиеся к строке состояния, не видны.
Windows10 Development – Управление файлами
В любом приложении одна из самых важных вещей – это данные. Если вы являетесь разработчиком .net , вы можете знать об изолированном хранилище, и та же концепция применяется в приложениях универсальной платформы Windows (UWP).
Расположение файлов
Это те области, где ваше приложение может получить доступ к данным. Приложение содержит некоторую область, которая является частной для этого конкретного приложения и недоступна для других, но есть много других областей, где вы можете хранить и сохранять свои данные в файле.
Ниже приведены краткие описания каждой папки.
S.No. | Папка и описание |
---|---|
1 |
Папка пакета приложения Диспетчер пакетов устанавливает все связанные с приложением файлы в папку пакета приложения, и приложение может только читать данные из этой папки. |
2 |
Локальная папка Приложения хранят локальные данные в локальной папке. Он может хранить данные до предела на устройстве хранения. |
3 |
Перемещаемая папка Настройки и свойства, связанные с приложением, хранятся в папке роуминга. Другие устройства также могут получить доступ к данным из этой папки. Он имеет ограниченный размер до 100 КБ на приложение. |
4 |
Временная папка Использование временного хранилища, и нет никакой гарантии, что оно все еще будет доступно при повторном запуске приложения. |
5 |
Издатель Поделиться Общее хранилище для всех приложений от одного издателя. Это заявлено в манифесте приложения. |
6 |
Loader Locker Используется для безопасного хранения объектов паролей. |
7 |
Один диск OneDrive – это бесплатное онлайн-хранилище, которое поставляется с вашей учетной записью Microsoft. |
8 |
облако Храните данные в облаке. |
9 |
Известные папки Эти папки уже известны, такие как папки «Мои рисунки», «Видео» и «Музыка». |
10 |
Съемное хранилище USB-накопитель или внешний жесткий диск и т. Д. |
Папка пакета приложения
Диспетчер пакетов устанавливает все связанные с приложением файлы в папку пакета приложения, и приложение может только читать данные из этой папки.
Локальная папка
Приложения хранят локальные данные в локальной папке. Он может хранить данные до предела на устройстве хранения.
Перемещаемая папка
Настройки и свойства, связанные с приложением, хранятся в папке роуминга. Другие устройства также могут получить доступ к данным из этой папки. Он имеет ограниченный размер до 100 КБ на приложение.
Временная папка
Использование временного хранилища, и нет никакой гарантии, что оно все еще будет доступно при повторном запуске приложения.
Издатель Поделиться
Общее хранилище для всех приложений от одного издателя. Это заявлено в манифесте приложения.
Loader Locker
Используется для безопасного хранения объектов паролей.
Один диск
OneDrive – это бесплатное онлайн-хранилище, которое поставляется с вашей учетной записью Microsoft.
облако
Храните данные в облаке.
Известные папки
Эти папки уже известны, такие как папки «Мои рисунки», «Видео» и «Музыка».
Съемное хранилище
USB-накопитель или внешний жесткий диск и т. Д.
API обработки файлов
В Windows 8 были добавлены новые API для обработки файлов. Эти API находятся в пространствах имен Windows.Storage и Windows.Storage.Streams . Вы можете использовать эти API вместо пространства имен System.IO.IsolatedStorage . С помощью этих API-интерфейсов будет проще перенести приложение Windows Phone в Магазин Windows, и вы сможете легко обновить свои приложения до будущих версий Windows.
Чтобы получить доступ к локальным, перемещаемым или временным папкам, вам нужно вызвать эти API –
StorageFolder localFolder = ApplicationData.Current.LocalFolder; StorageFolder roamingFolder = ApplicationData.Current.RoamingFolder; StorageFolder tempFolder = ApplicationData.Current.TemporaryFolder;
Чтобы создать новый файл в локальной папке, используйте следующий код –
StorageFolder localFolder = ApplicationData.Current.LocalFolder; StorageFile textFile = await localFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
Вот код для открытия вновь созданного файла и записи некоторого содержимого в этот файл.
using (IRandomAccessStream textStream = await textFile.OpenAsync(FileAccessMode.ReadWrite)) { using (DataWriter textWriter = new DataWriter(textStream)){ textWriter.WriteString(contents); await textWriter.StoreAsync(); } }
Вы можете снова открыть тот же файл из локальной папки, как показано в приведенном ниже коде.
using (IRandomAccessStream textStream = await textFile.OpenReadAsync()) { using (DataReader textReader = new DataReader(textStream)){ uint textLength = (uint)textStream.Size; await textReader.LoadAsync(textLength); contents = textReader.ReadString(textLength); } }
Чтобы понять, как работает чтение и запись данных, давайте рассмотрим простой пример. Ниже приведен код XAML, в который добавлены различные элементы управления.
<Page x:Class = "UWPFileHandling.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPFileHandling" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button x:Name = "readFile" Content = "Read Data From File" HorizontalAlignment = "Left" Margin = "62,518,0,0" VerticalAlignment = "Top" Height = "37" Width = "174" Click = "readFile_Click"/> <TextBox x:FieldModifier = "public" x:Name = "textBox" HorizontalAlignment = "Left" Margin = "58,145,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Height = "276" Width = "245"/>. <Button x:Name = "writeFile" Content = "Write Data to File" HorizontalAlignment = "Left" Margin = "64,459,0,0" VerticalAlignment = "Top" Click = "writeFile_Click"/> <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left" Margin = "386,149,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Height = "266" Width = "250" Foreground = "#FF6231CD"/> </Grid> </Page>
Ниже приведена реализация C # для различных событий, а также реализация класса FileHelper для чтения и записи данных в текстовый файл.
using System; using System.IO; using System.Threading.Tasks; using Windows.Storage; using Windows.Storage.Streams; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPFileHandling { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public partial class MainPage : Page { const string TEXT_FILE_NAME = "SampleTextFile.txt"; public MainPage(){ this.InitializeComponent(); } private async void readFile_Click(object sender, RoutedEventArgs e) { string str = await FileHelper.ReadTextFile(TEXT_FILE_NAME); textBlock.Text = str; } private async void writeFile_Click(object sender, RoutedEventArgs e) { string textFilePath = await FileHelper.WriteTextFile(TEXT_FILE_NAME, textBox.Text); } } public static class FileHelper { // Write a text file to the app's local folder. public static async Task<string> WriteTextFile(string filename, string contents) { StorageFolder localFolder = ApplicationData.Current.LocalFolder; StorageFile textFile = await localFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting); using (IRandomAccessStream textStream = await textFile.OpenAsync(FileAccessMode.ReadWrite)){ using (DataWriter textWriter = new DataWriter(textStream)){ textWriter.WriteString(contents); await textWriter.StoreAsync(); } } return textFile.Path; } // Read the contents of a text file from the app's local folder. public static async Task<string> ReadTextFile(string filename) { string contents; StorageFolder localFolder = ApplicationData.Current.LocalFolder; StorageFile textFile = await localFolder.GetFileAsync(filename); using (IRandomAccessStream textStream = await textFile.OpenReadAsync()){ using (DataReader textReader = new DataReader(textStream)){ uint textLength = (uint)textStream.Size; await textReader.LoadAsync(textLength); contents = textReader.ReadString(textLength); } } return contents; } } }
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
Теперь вы пишете что-то в текстовое поле и нажимаете кнопку «Записать данные в файл» . Программа запишет данные в текстовый файл в локальной папке. Если вы нажмете кнопку «Чтение данных из файла» , программа прочитает данные из того же текстового файла, который находится в локальной папке, и отобразит их в текстовом блоке.
Разработка для Windows 10 – база данных SQLite
Во многих приложениях существуют определенные типы данных, которые имеют какую-то связь друг с другом. Эти типы данных, которые трудно хранить в файле, могут быть сохранены в базе данных.
Если вы знакомы с типами баз данных, таких как базы данных SQL-сервера или Oracle в любом приложении, тогда очень легко понять базу данных SQLite .
Что такое SQLite?
SQLite – это программная библиотека, которая реализует автономное ядро транзакционной базы данных SQL с нулевой конфигурацией и нулевой конфигурацией.
Важные особенности –
-
SQLite является наиболее широко развернутым механизмом баз данных в мире.
-
Исходный код для SQLite является открытым исходным кодом.
-
Он оказал большое влияние на разработку игр и мобильных приложений благодаря своей мобильности и небольшому размеру.
SQLite является наиболее широко развернутым механизмом баз данных в мире.
Исходный код для SQLite является открытым исходным кодом.
Он оказал большое влияние на разработку игр и мобильных приложений благодаря своей мобильности и небольшому размеру.
Преимущества SQLite
Ниже приведены преимущества SQLite –
- Это очень легкая база данных.
- Он не зависит от платформы и работает на всех платформах.
- Он имеет небольшой след памяти.
- Это надежно.
- Нет необходимости в какой-либо настройке и установке.
- У него нет зависимостей.
Чтобы использовать SQLite в приложениях универсальной платформы Windows (UWP), вам необходимо выполнить следующие шаги.
-
Создайте новое универсальное пустое приложение для Windows с именем UWPSQLiteDemo .
-
Перейдите в меню « Сервис» и выберите «Расширения и обновления». Следующий диалог откроется.
Создайте новое универсальное пустое приложение для Windows с именем UWPSQLiteDemo .
Перейдите в меню « Сервис» и выберите «Расширения и обновления». Следующий диалог откроется.
- После выбора расширений и обновлений откроется следующее окно.
-
Теперь выберите опцию Online и найдите SQLite на левой панели.
-
Загрузите и установите SQLite для универсальной платформы приложений.
-
Теперь снова зайдите в меню «Инструменты» и выберите пункт меню « Диспетчер пакетов NuGet»> «Консоль диспетчера пакетов», как показано ниже.
Теперь выберите опцию Online и найдите SQLite на левой панели.
Загрузите и установите SQLite для универсальной платформы приложений.
Теперь снова зайдите в меню «Инструменты» и выберите пункт меню « Диспетчер пакетов NuGet»> «Консоль диспетчера пакетов», как показано ниже.
-
Напишите следующую команду в консоли диспетчера пакетов и нажмите Enter, чтобы выполнить эту команду:
Напишите следующую команду в консоли диспетчера пакетов и нажмите Enter, чтобы выполнить эту команду:
Install-Package SQLite.Net-PCL
-
Теперь щелкните правой кнопкой мыши на References в обозревателе решений и выберите Add References .
Теперь щелкните правой кнопкой мыши на References в обозревателе решений и выберите Add References .
- Следующий диалог откроется.
-
Выберите Расширения на левой панели в разделе « Универсальная Windows» , установите флажок «SQLite для универсальной платформы приложений» на средней панели и нажмите «ОК».
-
Теперь вы готовы пойти и использовать SQLite в своих приложениях UWP.
Выберите Расширения на левой панели в разделе « Универсальная Windows» , установите флажок «SQLite для универсальной платформы приложений» на средней панели и нажмите «ОК».
Теперь вы готовы пойти и использовать SQLite в своих приложениях UWP.
Вы можете создать базу данных, используя следующий код.
string path = Path.Combine(Windows.Storage.ApplicationData. Current.LocalFolder.Path, "db.sqlite"); SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path);
Для создания таблицы необходимо вызвать метод CreateTable с объектом имени таблицы.
conn.CreateTable<Customer>();
Вы можете вставить данные в свою таблицу, используя следующий код.
conn.Insert(new Customer(){ Name = textBox.Text, Age = textBox1.Text });
Ниже приведен код для извлечения данных из таблицы.
var query = conn.Table<Customer>(); string id = ""; string name = ""; string age = ""; foreach (var message in query) { id = id + " " + message.Id; name = name + " " + message.Name; age = age + " " + message.Age; }
Давайте разберемся, как создать базу данных, таблицу и как вставить и извлечь данные из базы данных с помощью простого примера. Мы добавим имя и возраст, а затем извлечем те же данные из таблицы. Ниже приведен код XAML, в который добавлены различные элементы управления.
<Page x:Class = "UWPSQLiteDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPSQLiteDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}" > <Button x:Name = "Retrieve" Content = "Retrieve" HorizontalAlignment = "Left" VerticalAlignment = "Top" Margin = "384,406,0,0" Click = "Retrieve_Click"/> <Button x:Name = "Add" Content = "Add" HorizontalAlignment = "Left" VerticalAlignment = "Top" Margin = "291,406,0,0" Click = "Add_Click"/> <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left" TextWrapping = "Wrap" Text = "Name" VerticalAlignment = "Top" Margin = "233,280,0,0" Width = "52"/> <TextBox x:Name = "textBox" HorizontalAlignment = "Left" TextWrapping = "Wrap" VerticalAlignment = "Top" Margin = "289,274,0,0" Width = "370"/> <TextBlock x:Name = "textBlock1" HorizontalAlignment = "Left" TextWrapping = "Wrap" Text = "Age" VerticalAlignment = "Top" Margin = "233,342,0,0" Width = "52"/> <TextBox x:Name = "textBox1" HorizontalAlignment = "Left" TextWrapping = "Wrap" VerticalAlignment = "Top" Margin = "289,336,0,0" Width = "191"/> <TextBlock x:Name = "textBlock2" HorizontalAlignment = "Left" Margin = "290,468,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "324" Height = "131"/> </Grid> </Page>
Ниже приведена реализация C # для событий и базы данных SQLite .
using SQLite.Net.Attributes; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPSQLiteDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { string path; SQLite.Net.SQLiteConnection conn; public MainPage(){ this.InitializeComponent(); path = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite"); conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), path); conn.CreateTable<Customer>(); } private void Retrieve_Click(object sender, RoutedEventArgs e) { var query = conn.Table<Customer>(); string id = ""; string name = ""; string age = ""; foreach (var message in query) { id = id + " " + message.Id; name = name + " " + message.Name; age = age + " " + message.Age; } textBlock2.Text = "ID: " + id + "nName: " + name + "nAge: " + age; } private void Add_Click(object sender, RoutedEventArgs e){ var s = conn.Insert(new Customer(){ Name = textBox.Text, Age = textBox1.Text }); } } public class Customer { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } public string Age { get; set; } } }
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
Введите Имя и Возраст и нажмите кнопку Добавить .
Теперь нажмите на кнопку Получить . Вы увидите следующие данные в текстовом блоке .
Поле идентификатора – это поле Первичный ключ и Автоинкремент, указанное в классе Customer.
[PrimaryKey, AutoIncrement] public int Id { get; set; }
Windows10 Dev – приложение связи
Связь между приложениями означает, что ваше приложение может общаться с другим приложением, установленным на том же устройстве, или общаться с ним. Это не новая функция в приложении универсальной платформы Windows (UWP), которая также была доступна в Windows 8.1.
В Windows 10 представлены некоторые новые и улучшенные способы для простой связи между приложениями на одном устройстве. Связь между двумя приложениями может осуществляться следующими способами:
- Одно приложение запускает другое приложение с некоторыми данными.
- Приложения просто обмениваются данными, не запуская ничего.
Основное преимущество обмена данными между приложениями заключается в том, что вы можете разбивать приложения на более мелкие части, которые можно легко обслуживать, обновлять и использовать.
Готовим ваше приложение
Если вы выполните действия, указанные ниже, другие приложения могут запустить ваше приложение.
-
Добавьте объявление протокола в манифест пакета приложения.
-
Дважды щелкните файл Package.appxmanifest , который доступен в обозревателе решений, как показано ниже.
-
Перейдите на вкладку « Декларация » и напишите название протокола, как показано ниже.
Добавьте объявление протокола в манифест пакета приложения.
Дважды щелкните файл Package.appxmanifest , который доступен в обозревателе решений, как показано ниже.
Перейдите на вкладку « Декларация » и напишите название протокола, как показано ниже.
-
Следующим шагом является добавление кода активации , чтобы приложение могло реагировать соответствующим образом при запуске другим приложением.
-
Чтобы ответить на активацию протокола, нам нужно переопределить метод OnActivation класса активации. Итак, добавьте следующий код в файл App.xaml.cs.
Следующим шагом является добавление кода активации , чтобы приложение могло реагировать соответствующим образом при запуске другим приложением.
Чтобы ответить на активацию протокола, нам нужно переопределить метод OnActivation класса активации. Итак, добавьте следующий код в файл App.xaml.cs.
protected override void OnActivated(IActivatedEventArgs args) { ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs; if (args != null){ Frame rootFrame = Window.Current.Content as Frame; // Do not repeat app initialization when the Window already has content, // just ensure that the window is active if (rootFrame == null){ // Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame(); // Set the default language rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0]; rootFrame.NavigationFailed += OnNavigationFailed; // Place the frame in the current Window Window.Current.Content = rootFrame; } if (rootFrame.Content == null){ // When the navigation stack isn't restored, navigate to the // first page, configuring the new page by passing required // information as a navigation parameter rootFrame.Navigate(typeof(MainPage), null); } // Ensure the current window is active Window.Current.Activate(); } }
-
Чтобы запустить приложение, вы можете просто использовать метод Launcher.LaunchUriAsync , который запустит приложение с протоколом, указанным в этом методе.
Чтобы запустить приложение, вы можете просто использовать метод Launcher.LaunchUriAsync , который запустит приложение с протоколом, указанным в этом методе.
await Windows.System.Launcher.LaunchUriAsync(new Uri("win10demo:?SomeData=123"));
Давайте разберемся с этим на простом примере, в котором у нас есть два приложения UWP с ProtocolHandlerDemo и FirstProtocolHandler .
В этом примере приложение ProtocolHandlerDemo содержит одну кнопку и, нажав на кнопку, откроет приложение FirstProtocolHandler .
Код XAML в приложении ProtocolHandlerDemo, который содержит одну кнопку, приведен ниже.
<Page x:Class = "ProtocolHandlerDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:ProtocolHandlerDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button x:Name = "LaunchButton" Content = " Launch First Protocol App" FontSize = "24" HorizontalAlignment = "Center" Click = "LaunchButton_Click"/> </Grid> </Page>
Ниже приведен код C #, в котором реализовано событие нажатия кнопки.
using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace ProtocolHandlerDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage(){ this.InitializeComponent(); } private async void LaunchButton_Click(object sender, RoutedEventArgs e) { await Windows.System.Launcher.LaunchUriAsync(new Uri("win10demo:?SomeData=123")); } } }
Теперь давайте посмотрим на таблицу приложений FirstProtocolHandler . Ниже приведен код XAML, в котором создается текстовый блок с некоторыми свойствами.
<Page x:Class = "FirstProtocolHandler.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:FirstProtocolHandler" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBlock Text = "You have successfully launch First Protocol Application" TextWrapping = "Wrap" Style = "{StaticResource SubtitleTextBlockStyle}" Margin = "30,39,0,0" VerticalAlignment = "Top" HorizontalAlignment = "Left" Height = "100" Width = "325"/> </Grid> </Page>
Реализация C # файла App.xaml.cs, в котором переопределено OnActicated , показана ниже. Добавьте следующий код в класс App в файле App.xaml.cs.
protected override void OnActivated(IActivatedEventArgs args) { ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs; if (args != null) { Frame rootFrame = Window.Current.Content as Frame; // Do not repeat app initialization when the Window already has content, // just ensure that the window is active if (rootFrame == null) { // Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame(); // Set the default language rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0]; rootFrame.NavigationFailed += OnNavigationFailed; // Place the frame in the current Window Window.Current.Content = rootFrame; } if (rootFrame.Content == null) { // When the navigation stack isn't restored navigate to the // first page, configuring the new page by passing required // information as a navigation parameter rootFrame.Navigate(typeof(MainPage), null); } // Ensure the current window is active Window.Current.Activate(); } }
Когда вы скомпилируете и запустите приложение ProtocolHandlerDemo на эмуляторе, вы увидите следующее окно.
Теперь, когда вы нажмете на кнопку, она откроет приложение FirstProtocolHandler, как показано ниже.
Разработка Windows 10 – Локализация
Windows используется во всем мире, на различных рынках и для целевой аудитории, которая различается по культуре, региону или языку. Локализация – это перевод ресурсов приложения в локализованные версии для определенных культур, которые поддерживает приложение.
Когда вы разрабатываете любое приложение только на одном языке, это означает, что вы просто ограничиваете свой бизнес и клиентов. Если вы хотите увеличить свою клиентскую базу, что также увеличит ваш бизнес, то ваше приложение должно быть доступно и доступно во всем мире. Экономичная локализация вашего продукта – один из лучших и наиболее экономичных способов привлечь больше клиентов.
В Windows 10 локализуемые приложения очень легко создавать с помощью файла resx , который является самым простым решением для локализации.
Давайте разберемся в этом на простом примере, выполнив все перечисленные ниже шаги.
Перевод ресурсов UI
Вы можете поместить строковые ресурсы для вашего пользовательского интерфейса в файлы ресурсов ( resw ) вместо того, чтобы помещать их непосредственно в код или разметку, а затем вы можете ссылаться на эти строки из своего кода или разметки. Следуйте приведенным ниже инструкциям, чтобы добавить строки в файлы ресурсов.
-
Создайте новое приложение универсальной платформы Windows (UWP).
-
В обозревателе решений щелкните правой кнопкой мыши проект и выберите « Добавить»> «Новая папка» .
Создайте новое приложение универсальной платформы Windows (UWP).
В обозревателе решений щелкните правой кнопкой мыши проект и выберите « Добавить»> «Новая папка» .
-
Измените имя новой папки на «Строки» .
-
Щелкните правой кнопкой мыши папку « Строки » и добавьте новую папку с именем « en-US ». Это соглашения об именах, относящиеся к языку и названию страны / региона, и их можно найти на странице справки API поддержки национальных языков (NLS) msdn.microsoft.com .
-
Щелкните правой кнопкой мыши папку en-US и выберите « Добавить»> «Новый элемент» .
Измените имя новой папки на «Строки» .
Щелкните правой кнопкой мыши папку « Строки » и добавьте новую папку с именем « en-US ». Это соглашения об именах, относящиеся к языку и названию страны / региона, и их можно найти на странице справки API поддержки национальных языков (NLS) msdn.microsoft.com .
Щелкните правой кнопкой мыши папку en-US и выберите « Добавить»> «Новый элемент» .
- Следующий диалог откроется.
-
Выберите «Файл ресурсов (.resw)» и нажмите кнопку « Добавить» .
-
Теперь давайте перейдем к файлу XAML и добавим элемент управления Hub с некоторыми свойствами, как показано ниже.
Выберите «Файл ресурсов (.resw)» и нажмите кнопку « Добавить» .
Теперь давайте перейдем к файлу XAML и добавим элемент управления Hub с некоторыми свойствами, как показано ниже.
<Page x:Class = "UWPLocalizationDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPLocalizationDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub x:Name = "textBlock" x:Uid = "HubControl" Background = "Black" Foreground = "White" Header = "Localization Demo"/> </Grid> </Page>
-
x: Uid = “HubControl” – это идентификаторы, которые используются для локализации
-
Теперь, когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
x: Uid = “HubControl” – это идентификаторы, которые используются для локализации
Теперь, когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
Вся информация, связанная с концентратором, такая как заголовок, передний план и цвет фона, задается в XAML.
-
Теперь добавьте некоторую информацию в файл Resource.resw в папку Strings / en-US, как показано ниже.
Теперь добавьте некоторую информацию в файл Resource.resw в папку Strings / en-US, как показано ниже.
-
Вам нужно связать каждый элемент управления, которому нужен локализованный текст, с. Resw файл. Вы можете сделать это, используя атрибут x: Uid в ваших элементах XAML, например так:
-
x: Uid = “HubControl” используется в файле resw для назначения строки для цвета заголовка, переднего плана и фона.
-
Вам нужно связать каждый элемент управления, которому нужен локализованный текст, с. Resw файл. Вы можете сделать это, используя атрибут x: Uid в ваших элементах XAML, например так:
x: Uid = “HubControl” используется в файле resw для назначения строки для цвета заголовка, переднего плана и фона.
-
Теперь, когда вы скомпилируете и запустите свое приложение на эмуляторе, вы увидите следующее окно. Вы можете видеть, что значения цвета заголовка, переднего плана и фона выбираются из файла Resources.resw .
Теперь, когда вы скомпилируете и запустите свое приложение на эмуляторе, вы увидите следующее окно. Вы можете видеть, что значения цвета заголовка, переднего плана и фона выбираются из файла Resources.resw .
-
Вы можете добавить другие файлы Resource.resw для других языков, таких как французский, немецкий, японский и т. Д. Вручную, как мы это сделали для англо-американских, но Microsoft также предоставляет многоязычный набор инструментов приложения, с помощью которого вы можете легко перевести ваш Resource.resw на других языках.
-
Перейдите в меню « Инструменты»> «Расширения и обновления» и выполните поиск инструментария многоязычного приложения .
Вы можете добавить другие файлы Resource.resw для других языков, таких как французский, немецкий, японский и т. Д. Вручную, как мы это сделали для англо-американских, но Microsoft также предоставляет многоязычный набор инструментов приложения, с помощью которого вы можете легко перевести ваш Resource.resw на других языках.
Перейдите в меню « Инструменты»> «Расширения и обновления» и выполните поиск инструментария многоязычного приложения .
-
Загрузите и установите этот инструментарий. После завершения установки перезапустите Visual Studio и откройте тот же проект.
-
Теперь включите этот инструментарий в меню « Инструменты»> «Многоязычный инструментарий приложения» .
Загрузите и установите этот инструментарий. После завершения установки перезапустите Visual Studio и откройте тот же проект.
Теперь включите этот инструментарий в меню « Инструменты»> «Многоязычный инструментарий приложения» .
-
Теперь вы можете добавить перевод для других языков.
-
Щелкните правой кнопкой мыши проект в обозревателе решений и выберите в меню пункт « Многоязычный набор инструментов»> «Добавить языки перевода» .
Теперь вы можете добавить перевод для других языков.
Щелкните правой кнопкой мыши проект в обозревателе решений и выберите в меню пункт « Многоязычный набор инструментов»> «Добавить языки перевода» .
-
Откроется следующее диалоговое окно « Языки перевода ». Вы можете выбрать любой язык для локализации вашего приложения для этих культур.
Откроется следующее диалоговое окно « Языки перевода ». Вы можете выбрать любой язык для локализации вашего приложения для этих культур.
-
Давайте выберем немецкий язык и нажмем кнопку ОК .
Давайте выберем немецкий язык и нажмем кнопку ОК .
-
Вы также можете видеть, что файл Resources.resw создается внутри папки Strings de .
-
Теперь вы увидите, что в файл * .xlf добавлен еще один MultiLingualResources . Дважды щелкните по этому файлу, чтобы открыть многоязычный редактор, чтобы проверить и проверить переведенные строки и внести некоторые изменения, если это необходимо.
Вы также можете видеть, что файл Resources.resw создается внутри папки Strings de .
Теперь вы увидите, что в файл * .xlf добавлен еще один MultiLingualResources . Дважды щелкните по этому файлу, чтобы открыть многоязычный редактор, чтобы проверить и проверить переведенные строки и внести некоторые изменения, если это необходимо.
-
Внесите изменения и убедитесь, что цвет фона изменился на коричневый, а текст заголовка правильно переведен на немецкий язык.
-
Как и в приведенном выше примере, цвет фона Hub изменился с синего на коричневый, а цвет переднего плана остался прежним.
-
Теперь откройте Resources.resw , который находится внутри папки Strings de .
Внесите изменения и убедитесь, что цвет фона изменился на коричневый, а текст заголовка правильно переведен на немецкий язык.
Как и в приведенном выше примере, цвет фона Hub изменился с синего на коричневый, а цвет переднего плана остался прежним.
Теперь откройте Resources.resw , который находится внутри папки Strings de .
-
Вы можете видеть, что здесь упоминаются только две строки, потому что мы не изменили цвет переднего плана в многоязычном редакторе.
Вы можете видеть, что здесь упоминаются только две строки, потому что мы не изменили цвет переднего плана в многоязычном редакторе.
Чтобы проверить локализованную версию вашего приложения, измените культуру вашего компьютера. Чтобы изменить культуру своей машины, следуйте приведенным инструкциям.
- Перейдем к настройкам ПК и выберите «Время и язык».
-
На левой панели выберите « Регионы и язык» и нажмите « Добавить язык» .
На левой панели выберите « Регионы и язык» и нажмите « Добавить язык» .
-
Выберите немецкий немецкий язык, как показано выше, который откроет другое диалоговое окно.
Выберите немецкий немецкий язык, как показано выше, который откроет другое диалоговое окно.
-
Теперь выберите немецкий (Германия) и закройте это диалоговое окно.
Теперь выберите немецкий (Германия) и закройте это диалоговое окно.
- Сделайте Deutsch языком по умолчанию.
- Теперь запустите ваше приложение, оно отобразит следующее окно.
- Теперь вы можете увидеть вывод вашей заявки на немецком языке.
Разработка для Windows 10 – жизненный цикл
Исторически в Windows была среда, в которой пользователи могли запускать несколько приложений одновременно. Пользователь может легко переключаться между различными приложениями. Эта модель не подходит для телефонов или планшетов, где использование обычно ориентировано на одно приложение.
Одной из наиболее важных задач, стоящих перед разработчиками приложений для Магазина Windows 8, станет управление и понимание жизненного цикла приложения. Если вы создавали приложения для Windows Phone, многое из этого было бы знакомо.
-
В Windows 8 операционная система управляет временем жизни приложения, и хотя пользователь может завершить приложение, обычно пользователь открывает новые приложения, не прерывая сознательно запущенные приложения.
-
Универсальная платформа Windows (UWP) для Windows 10 решает эти проблемы, предлагая пользователям настольных компьютеров несколько интересных вещей, позволяющих запускать несколько приложений с несколькими окнами.
В Windows 8 операционная система управляет временем жизни приложения, и хотя пользователь может завершить приложение, обычно пользователь открывает новые приложения, не прерывая сознательно запущенные приложения.
Универсальная платформа Windows (UWP) для Windows 10 решает эти проблемы, предлагая пользователям настольных компьютеров несколько интересных вещей, позволяющих запускать несколько приложений с несколькими окнами.
Приложения Windows могут существовать в трех состояниях на базовом уровне, как показано ниже.
-
Бег
-
подвешенный
-
прекратить
Бег
подвешенный
прекратить
-
Когда пользователь запускает / активирует какое-либо приложение, оно переходит в рабочее состояние.
-
Приложения могут быть приостановлены, если пользователь не использует их, и они больше не находятся на переднем плане.
-
Из приостановленного состояния приложения могут либо возобновить это приложение, либо завершить работу ОС, чтобы восстановить системные ресурсы.
Когда пользователь запускает / активирует какое-либо приложение, оно переходит в рабочее состояние.
Приложения могут быть приостановлены, если пользователь не использует их, и они больше не находятся на переднем плане.
Из приостановленного состояния приложения могут либо возобновить это приложение, либо завершить работу ОС, чтобы восстановить системные ресурсы.
Переход состояния процесса
Важно понимать переходы состояний процесса в работающем приложении. Когда пользователь впервые запускает приложение, отображается заставка, а затем приложение запускается.
Процесс можно объяснить следующим образом –
-
Когда приложение приостанавливается, ваше приложение получает пять секунд для обработки этого приостановленного события.
-
Когда приложение приостановлено, абсолютно не выполняется код и ресурсы не выделяются.
-
Когда это возобновляется, приложение уведомляется, что оно возобновило. Если вы выходите из приостановленного состояния, вам не нужно предпринимать никаких действий.
-
Под давлением памяти ваше приложение может быть прекращено.
-
Помните, что вы не будете уведомлены в этот момент, и поэтому любое сохранение, которое вы делаете, вы должны делать, когда входите в состояние приостановленного приложения.
Когда приложение приостанавливается, ваше приложение получает пять секунд для обработки этого приостановленного события.
Когда приложение приостановлено, абсолютно не выполняется код и ресурсы не выделяются.
Когда это возобновляется, приложение уведомляется, что оно возобновило. Если вы выходите из приостановленного состояния, вам не нужно предпринимать никаких действий.
Под давлением памяти ваше приложение может быть прекращено.
Помните, что вы не будете уведомлены в этот момент, и поэтому любое сохранение, которое вы делаете, вы должны делать, когда входите в состояние приостановленного приложения.
Когда приложение переходит назад и вперед между состояниями « Работа» и « Приостановлено» , запускаются события приостановки и возобновления соответственно.
Иногда вам нужно сохранить данные. Затем вы должны вызывать асинхронные методы, как показано ниже.
Application.Current.Suspending += new SuspendingEventHandler(App_Suspending); async void App_Suspending(Object sender, Windows.ApplicationModel.SuspendingEventArgs e){ // Create a simple setting localSettings.Values["FirstName"] = fName.Text; localSettings.Values["LastName"] = lName.Text; localSettings.Values["Email"] = email.Text; }
Application.Current.Resuming += new EventHandler<Object>(App_Resuming); private void App_Resuming(Object sender, Object e){ fName.Text = localSettings.Values["FirstName"]; lName.Text = localSettings.Values["LastName"]; email.Text = localSettings.Values["Email"]; }
Давайте рассмотрим пример, в котором добавляются элементы управления, как показано в приведенном ниже файле XAML.
<Page x:Class = "UWPLifeCycleDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPLifeCycleDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub Header = "Details" /> <StackPanel VerticalAlignment = "Top" HorizontalAlignment = "Left" Margin = "12,64,0,0"> <TextBox Header = "First Name" Text = "{Binding FirstName, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" Width = "200" /> <TextBox Header = "Last Name" Text = "{Binding LastName, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" Width = "200" /> <TextBox Header = "Email" Text = "{Binding Email, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" Width = "200" /> <Button Margin = "0,12">Submit</Button> </StackPanel> </Grid> </Page>
Ниже приведен код C #, в котором реализованы события Suspend и Resume. Текущие данные будут сохранены в событии приостановки в локальных настройках, а затем данные будут извлечены в событии возобновления из локальных настроек, как показано ниже.
using System; using System.ComponentModel; using System.Runtime.CompilerServices; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace UWPLifeCycleDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page{ var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; public MainPage() { this.InitializeComponent(); Application.Current.Suspending += new SuspendingEventHandler(App_Suspending); Application.Current.Resuming += new EventHandler<Object>(App_Resuming); } async void App_Suspending(Object sender, Windows.ApplicationModel.SuspendingEventArgs e){ // Create a simple setting localSettings.Values["FirstName"] = fName.Text; localSettings.Values["LastName"] = lName.Text; localSettings.Values["Email"] = email.Text; } private void App_Resuming(Object sender, Object e){ fName.Text = localSettings.Values["FirstName"]; lName.Text = localSettings.Values["LastName"]; email.Text = localSettings.Values["Email"]; } } public abstract class BindableBase : INotifyPropertyChanged { private string _FirstName = default(string); public string FirstName { get { return _FirstName; } set { Set(ref _FirstName, value); } } private string _LastName = default(string); public string LastName { get { return _LastName; } set { Set(ref _LastName, value); } } private string _Email = default(string); public string Email { get { return _Email; } set { Set(ref _Email, value); } } public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged([CallerMemberName]string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public void Set<T>(ref T storage, T value, [CallerMemberName()]string propertyName = null){ if (!object.Equals(storage, value)){ storage = value; RaisePropertyChanged(propertyName); } } } }
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно. Теперь напишите желаемую информацию.
Перейдем в выпадающее меню «События жизненного цикла» и выберите « Приостановлено» . Теперь ваше приложение будет приостановлено, а нужная информация будет сохранена в локальных настройках. Смотрите скриншот, приведенный ниже.
Теперь, когда вы хотите возобновить работу приложения, выберите пункт « Продолжить» в меню « События жизненного цикла» .
Теперь вы увидите, что сохраненная информация извлекается из локальных настроек, и приложение возобновляется в том же состоянии, из которого оно было приостановлено.
Windows10 Dev – Фоновое выполнение
Универсальная платформа Windows (UWP) представляет новые механизмы, которые позволяют приложениям выполнять некоторые функции, пока приложение не выполняется на переднем плане. UWP также увеличивает способность приложений продлевать время их выполнения в фоновом режиме для фоновых задач и триггеров . Фоновое выполнение является реальным дополнительным хвостом к жизненному циклу приложения.
Важные особенности фоновых задач –
-
Фоновая задача запускается системным или временным событием и может быть ограничена одним или несколькими условиями.
-
Когда запускается фоновая задача, связанный с ней обработчик запускается и выполняет работу фоновой задачи.
-
Фоновая задача может выполняться, даже если приложение, зарегистрировавшее фоновую задачу, приостановлено.
-
Они являются частью стандартной платформы приложений и по существу предоставляют приложению возможность регистрироваться для системного события (триггера). Когда это событие происходит, они запускают предопределенный блок кода в фоновом режиме. Системные триггеры включают в себя такие события, как изменения сетевого подключения или системного часового пояса.
-
Фоновое выполнение не гарантируется, поэтому оно не подходит для критических функций и возможностей.
-
ОС имеет ограничение на количество фоновых задач, которые могут выполняться одновременно. Таким образом, даже когда триггер срабатывает и условия выполняются, задача все равно не может быть запущена.
Фоновая задача запускается системным или временным событием и может быть ограничена одним или несколькими условиями.
Когда запускается фоновая задача, связанный с ней обработчик запускается и выполняет работу фоновой задачи.
Фоновая задача может выполняться, даже если приложение, зарегистрировавшее фоновую задачу, приостановлено.
Они являются частью стандартной платформы приложений и по существу предоставляют приложению возможность регистрироваться для системного события (триггера). Когда это событие происходит, они запускают предопределенный блок кода в фоновом режиме. Системные триггеры включают в себя такие события, как изменения сетевого подключения или системного часового пояса.
Фоновое выполнение не гарантируется, поэтому оно не подходит для критических функций и возможностей.
ОС имеет ограничение на количество фоновых задач, которые могут выполняться одновременно. Таким образом, даже когда триггер срабатывает и условия выполняются, задача все равно не может быть запущена.
Создать и зарегистрировать фоновую задачу
Создайте класс фоновой задачи и зарегистрируйте его для запуска, когда ваше приложение не на переднем плане. Вы можете запустить код в фоновом режиме, написав классы, которые реализуют интерфейс IBackgroundTask . В следующем примере кода показана базовая отправная точка для класса фоновых задач.
public sealed class MyBackgroundTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance){ // write code } }
Вы можете запросить доступ для фоновой задачи следующим образом.
var access = await BackgroundExecutionManager.RequestAccessAsync(); switch (access) { case BackgroundAccessStatus.Unspecified: break; case BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity: break; case BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity: break; case BackgroundAccessStatus.Denied: break; default: break; }
Чтобы создать и зарегистрировать фоновое задание, используйте следующий код.
var task = new BackgroundTaskBuilder { Name = "My Task", TaskEntryPoint = typeof(BackgroundStuff.MyBackgroundTask).ToString() }; var trigger = new ApplicationTrigger(); task.SetTrigger(trigger); task.Register(); await trigger.RequestAsync();
Давайте разберем простой пример фоновой задачи, выполнив все приведенные ниже шаги.
-
Создайте новый пустой проект UWP «UWPBackgroundDemo» и добавьте одну кнопку в файл XAML.
Создайте новый пустой проект UWP «UWPBackgroundDemo» и добавьте одну кнопку в файл XAML.
<Page x:Class = "UWPBackgroundDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPBackgroundDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button x:Name = "button" Content = "Button" HorizontalAlignment = "Left" Margin = "159,288,0,0" VerticalAlignment = "Top" Click = "button_Click"/> </Grid> </Page>
-
Ниже приведена реализация события нажатия кнопки, в которой регистрируется фоновая задача.
Ниже приведена реализация события нажатия кнопки, в которой регистрируется фоновая задача.
using System; using Windows.ApplicationModel.Background; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPBackgroundDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private async void button_Click(object sender, RoutedEventArgs e) { var access = await BackgroundExecutionManager.RequestAccessAsync(); switch (access){ case BackgroundAccessStatus.Unspecified: break; case BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity: break; case BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity: break; case BackgroundAccessStatus.Denied: break; default: break; } var task = new BackgroundTaskBuilder { Name = "My Task", TaskEntryPoint = typeof(BackgroundStuff.MyBackgroundTask).ToString() }; var trigger = new ApplicationTrigger(); task.SetTrigger(trigger); var condition = new SystemCondition(SystemConditionType.InternetAvailable); task.Register(); await trigger.RequestAsync(); } } }
-
Теперь создайте другой проект, но на этот раз выберите компонент среды выполнения Windows (Universal Windows) из меню и присвойте этому фону имя Background background .
Теперь создайте другой проект, но на этот раз выберите компонент среды выполнения Windows (Universal Windows) из меню и присвойте этому фону имя Background background .
-
Ниже приведен код C #. который содержит имплантацию класса MyBackgroundTask и будет запускать фоновую задачу.
Ниже приведен код C #. который содержит имплантацию класса MyBackgroundTask и будет запускать фоновую задачу.
using Windows.ApplicationModel.Background; using Windows.UI.Notifications; namespace BackgroundStuff { public sealed class MyBackgroundTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { SendToast("Hi this is background Task"); } public static void SendToast(string message) { var template = ToastTemplateType.ToastText01; var xml = ToastNotificationManager.GetTemplateContent(template); var elements = xml.GetElementsByTagName("Test"); var text = xml.CreateTextNode(message); elements[0].AppendChild(text); var toast = new ToastNotification(xml); ToastNotificationManager.CreateToastNotifier().Show(toast); } } }
-
Чтобы сделать этот проект доступным в проекте UWPBackgroundDemo , щелкните правой кнопкой мыши References> Add References в Solution Explorer и добавьте проект BackgroundStuff .
Чтобы сделать этот проект доступным в проекте UWPBackgroundDemo , щелкните правой кнопкой мыши References> Add References в Solution Explorer и добавьте проект BackgroundStuff .
-
Теперь давайте перейдем к файлу Package.appxmanifest проекта UWPBackgroundDemo и добавим следующую информацию на вкладке «Объявления».
Теперь давайте перейдем к файлу Package.appxmanifest проекта UWPBackgroundDemo и добавим следующую информацию на вкладке «Объявления».
-
Сначала создайте проект Background stuff, затем создайте и выполните проект UWPBackgroundDemo .
-
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
Сначала создайте проект Background stuff, затем создайте и выполните проект UWPBackgroundDemo .
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
-
Когда вы нажмете кнопку , он запустит фоновое задание и покажет уведомление в правом конце вашего окна.
Когда вы нажмете кнопку , он запустит фоновое задание и покажет уведомление в правом конце вашего окна.
Разработка Windows 10 – Услуги
В этой главе мы узнаем о том, как приложения UWP могут помогать или предоставлять услуги другим приложениям универсальной платформы Windows (UWP). На самом деле, эта глава является расширением главы Фоновое выполнение и является ее частным случаем.
-
В Windows 10 служба приложений – это способ или механизм, позволяющий приложению предоставлять службы другим приложениям.
-
Служба приложения работает в виде фоновой задачи.
-
Приложения Foreground могут вызывать службу приложений в другом приложении для выполнения задач в фоновом режиме.
В Windows 10 служба приложений – это способ или механизм, позволяющий приложению предоставлять службы другим приложениям.
Служба приложения работает в виде фоновой задачи.
Приложения Foreground могут вызывать службу приложений в другом приложении для выполнения задач в фоновом режиме.
Сервисы приложений похожи на веб-сервисы, но сервисы приложений используются на устройстве с Windows 10.
Приложения универсальной платформы Windows (UWP) могут взаимодействовать с другим приложением UWP различными способами –
- Сопоставление URI с использованием LaunchUriAsync
- Связывание файлов с использованием LaunchFileAsync
- Запуск для результатов с помощью LaunchUriForResultsAsync
- Сервисы приложений
Первые три способа используются, когда оба приложения находятся на переднем плане, но службы приложений используются в фоновом режиме, и в этом случае клиентское приложение должно быть на переднем плане и доступно для использования службы приложений.
Сервисы приложений очень полезны в приложениях, где предоставляются невизуальные сервисы, например, сканер штрих-кода, в котором приложение на переднем плане берет изображение и отправляет эти байты сервисам приложения для идентификации штрих-кода.
Чтобы понять все эти концепции, давайте создадим новый проект UWP с именем AppServiceProvider в Microsoft Visual Studio 2015.
Теперь в файле Package.appmenifest добавьте следующую информацию.
Чтобы создать службу приложения, которая может вызываться приложениями переднего плана, добавим в решение новый проект компонента среды выполнения Windows с именем MyAppService , поскольку службы приложения реализованы в виде фоновой задачи.
Добавьте ссылку на проект MyAppService в проекте AppServiceProvider .
Теперь удалите файл class1.cs из проекта MyAppService и добавьте новый класс с именем инвентаря, который будет реализовывать интерфейс IBackgrounTask .
Интерфейс IBackgrounTask имеет только один метод «Выполнить», который необходимо реализовать для фоновой задачи.
public sealed class Inventory : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { } }
При создании фоновой задачи вызывается метод Run (), а после завершения метода Run фоновые задачи завершаются. Чтобы не отставать от фоновой задачи, обслуживать запросы, код требует отсрочки.
Код служб приложения находится в OnRequestedReceived () . В этом примере индекс для элемента инвентаря передается службе, чтобы получить имя и цену указанного элемента инвентаря.
private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { // Get a deferral because we use an awaitable API below to respond to the message }
Ниже приведена полная реализация класса Inventory в C #.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.ApplicationModel.AppService; using Windows.ApplicationModel.Background; using Windows.Foundation.Collections; namespace MyAppService{ public sealed class Inventory : IBackgroundTask { private BackgroundTaskDeferral backgroundTaskDeferral; private AppServiceConnection appServiceconnection; private String[] inventoryItems = new string[] { "Robot vacuum", "Chair" }; private double[] inventoryPrices = new double[] { 129.99, 88.99 }; public void Run(IBackgroundTaskInstance taskInstance) { this.backgroundTaskDeferral = taskInstance.GetDeferral(); taskInstance.Canceled += OnTaskCanceled; var details = taskInstance.TriggerDetails as AppServiceTriggerDetails; appServiceconnection = details.AppServiceConnection; appServiceconnection.RequestReceived += OnRequestReceived; } private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { var messageDeferral = args.GetDeferral(); ValueSet message = args.Request.Message; ValueSet returnData = new ValueSet(); string command = message["Command"] as string; int? inventoryIndex = message["ID"] as int?; if (inventoryIndex.HasValue && inventoryIndex.Value >= 0 && inventoryIndex.Value < inventoryItems.GetLength(0)) { switch (command) { case "Price": { returnData.Add("Result", inventoryPrices[inventoryIndex.Value]); returnData.Add("Status", "OK"); break; } case "Item": { returnData.Add("Result", inventoryItems[inventoryIndex.Value]); returnData.Add("Status", "OK"); break; } default: { returnData.Add("Status", "Fail: unknown command"); break; } } else { returnData.Add("Status", "Fail: Index out of range"); } } await args.Request.SendResponseAsync(returnData); messageDeferral.Complete(); } private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason){ if (this.backgroundTaskDeferral != null) { // Complete the service deferral. this.backgroundTaskDeferral.Complete(); } } } }
Давайте создадим клиентское приложение, добавив новый пустой UWP-проект ClientApp и добавив одну кнопку, одно текстовое поле и два текстовых блока, как показано ниже в файле XAML.
<Page x:Class = "ClientApp.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:ClientApp" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBlock HorizontalAlignment = "Left" Text = "Enter Item No." Margin = "52,40,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Height = "32" Width = "268"/> <Button x:Name = "button" Content = "Get Info" HorizontalAlignment = "Left" Margin = "255,96,0,0" VerticalAlignment = "Top" Click = "button_Click"/> <TextBox x:Name = "textBox" HorizontalAlignment = "Left" Margin = "52,96,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "168"/> <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left" Margin = "52,190,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Height = "32" Width = "268"/> </Grid> </Page>
Ниже приведена реализация события нажатия кнопки, при которой запрашиваются службы приложения.
using System; using Windows.ApplicationModel.AppService; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace ClientApp { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { private AppServiceConnection inventoryService; public MainPage() { this.InitializeComponent(); } private async void button_Click(object sender, RoutedEventArgs e){ // Add the connection. if (this.inventoryService == null) { this.inventoryService = new AppServiceConnection(); this.inventoryService.AppServiceName = "com.microsoft.inventory"; this.inventoryService.PackageFamilyName = "bb1a8478-8005-46869923-e525ceaa26fc_4sz2ag3dcq60a"; var status = await this.inventoryService.OpenAsync(); if (status != AppServiceConnectionStatus.Success) { button.Content = "Failed to connect"; return; } } // Call the service. int idx = int.Parse(textBox.Text); var message = new ValueSet(); message.Add("Command", "Item"); message.Add("ID", idx); AppServiceResponse response = await this.inventoryService.SendMessageAsync(message); string result = ""; if (response.Status == AppServiceResponseStatus.Success) { // Get the data that the service sent to us. if (response.Message["Status"] as string == "OK") { result = response.Message["Result"] as string; } } message.Clear(); message.Add("Command", "Price"); message.Add("ID", idx); response = await this.inventoryService.SendMessageAsync(message); if (response.Status == AppServiceResponseStatus.Success){ // Get the data that the service sent to us. if (response.Message["Status"] as string == "OK") { result += " : Price = " + "$"+ response.Message["Result"] as string; } } textBlock.Text = result; } } }
Чтобы запустить это приложение, вам нужно установить проект ClientApp в качестве запускаемого проекта в обозревателе решений, а затем развернуть это решение из меню «Сборка»> «Развернуть решение».
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно. В сервисы приложений мы только что добавили информацию о двух элементах. Таким образом, вы можете ввести 0 или 1, чтобы получить информацию об этих элементах.
Когда вы вводите 0 и нажимаете кнопку, он запускает службу приложений в качестве фоновой задачи и отображает информацию об элементе в текстовом блоке .
Разработка для Windows 10 – веб-платформа
В Windows 10 разработчикам очень легко создать приложение универсальной платформы Windows (UWP) и разместить свой веб-сайт в этом приложении, которое затем можно опубликовать в Магазине Windows для загрузки.
преимущества
-
С помощью этой новой функции в Windows 10 веб-разработчики могут легко преобразовывать компоненты своих веб-сайтов в приложения Windows.
-
Однако все эти компоненты будут по-прежнему размещаться удаленно на своих собственных веб-серверах.
-
Кроме того, они также могут получить доступ к универсальным API-интерфейсам, которые позволят разработчикам получить доступ к некоторым интересным вещам, таким как уведомления, камера, календарь, Cortana и другие.
С помощью этой новой функции в Windows 10 веб-разработчики могут легко преобразовывать компоненты своих веб-сайтов в приложения Windows.
Однако все эти компоненты будут по-прежнему размещаться удаленно на своих собственных веб-серверах.
Кроме того, они также могут получить доступ к универсальным API-интерфейсам, которые позволят разработчикам получить доступ к некоторым интересным вещам, таким как уведомления, камера, календарь, Cortana и другие.
Microsoft надеется, что эта функция и способность привлечет больше разработчиков для написания приложений для платформы Windows 10, в том числе.
- Настольные компьютеры
- Смартфоны
- Xbox
- таблетки
- HoloLens и другие устройства
В настоящее время есть только одна проблема с этой функцией – безопасность. Очевидно, что Microsoft необходимо решить эту проблему как можно скорее.
Давайте разберемся с помощью примера, в котором мы будем размещать веб-сайт и преобразовывать этот веб-сайт в приложение Windows.
Следуйте приведенным ниже инструкциям.
-
Создайте новый универсальный проект Windows из « Файл»> «Создать»> «Проект» .
Создайте новый универсальный проект Windows из « Файл»> «Создать»> «Проект» .
-
Выберите « JavaScript»> «Windows»> «Универсальный» на левой панели нового проекта и диалогового окна.
-
На средней панели выберите « Пустое приложение» (Universal Windows) .
-
Напишите в поле имени UWPWebApp и нажмите кнопку ОК .
-
Если вы посмотрите в окно Solution Explorer , вы увидите некоторые файлы и папки.
Выберите « JavaScript»> «Windows»> «Универсальный» на левой панели нового проекта и диалогового окна.
На средней панели выберите « Пустое приложение» (Universal Windows) .
Напишите в поле имени UWPWebApp и нажмите кнопку ОК .
Если вы посмотрите в окно Solution Explorer , вы увидите некоторые файлы и папки.
-
Удалите папки css, js, WinJS и файл default.html , потому что в этом примере мы просто размещаем веб-сайт и предполагаем, что все содержимое находится на удаленном сервере. Поэтому нам не нужно большинство локальных файлов.
-
После удаления вышеупомянутых файлов и папок, теперь дважды щелкните файл package.appxmanifest, и вы увидите следующее окно.
Удалите папки css, js, WinJS и файл default.html , потому что в этом примере мы просто размещаем веб-сайт и предполагаем, что все содержимое находится на удаленном сервере. Поэтому нам не нужно большинство локальных файлов.
После удаления вышеупомянутых файлов и папок, теперь дважды щелкните файл package.appxmanifest, и вы увидите следующее окно.
-
Теперь укажите URL-адрес веб-сайта, заменив default.html в поле «Начальная страница» URL-адресом. В целях демонстрации мы будем использовать URL-адрес https://www.google.com.pk/ веб-сайта.
Теперь укажите URL-адрес веб-сайта, заменив default.html в поле «Начальная страница» URL-адресом. В целях демонстрации мы будем использовать URL-адрес https://www.google.com.pk/ веб-сайта.
-
Теперь перейдите на вкладку Content URI и определите правило и права доступа для вашего веб-приложения.
Теперь перейдите на вкладку Content URI и определите правило и права доступа для вашего веб-приложения.
-
В поле URI укажите ссылку на веб-сайт, а затем выберите « Включить» в раскрывающемся списке «Правило» и « Все из WinRT Access» .
-
Когда вы запустите это приложение, вы увидите стартовую страницу Google в своем приложении, как показано ниже.
В поле URI укажите ссылку на веб-сайт, а затем выберите « Включить» в раскрывающемся списке «Правило» и « Все из WinRT Access» .
Когда вы запустите это приложение, вы увидите стартовую страницу Google в своем приложении, как показано ниже.
Windows10 Dev – Connected Experience
Как мы уже знаем, в Windows 10 мы можем создать приложение, которое можно запускать и запускать на нескольких устройствах Windows 10. Давайте предположим, что у нас есть эти разные устройства, и мы хотим, чтобы это было похоже на то, что это одно приложение, даже если оно работает на разных устройствах.
В универсальной платформе Windows (UWP) вы можете запустить одно приложение на всех устройствах Windows 10 и дать пользователю ощущение, что это одно приложение. Это известно как опыт соединения .
Важные особенности связанного опыта –
-
Windows 10 – это первый шаг в эру персональных компьютеров, когда ваши приложения, сервисы и контент могут легко и без проблем перемещаться с вами на разных устройствах.
-
С подключенным опытом вы можете легко поделиться своими данными и личными настройками, связанными с этим приложением, и оно будет доступно на всех устройствах.
Windows 10 – это первый шаг в эру персональных компьютеров, когда ваши приложения, сервисы и контент могут легко и без проблем перемещаться с вами на разных устройствах.
С подключенным опытом вы можете легко поделиться своими данными и личными настройками, связанными с этим приложением, и оно будет доступно на всех устройствах.
В этой главе мы узнаем –
-
где эти общие данные или настройки будут храниться так, чтобы они могли быть доступны на ваших устройствах для этого одного приложения.
-
как пользователь идентифицирован; что это один и тот же пользователь, который использует одно и то же приложение на разных устройствах.
где эти общие данные или настройки будут храниться так, чтобы они могли быть доступны на ваших устройствах для этого одного приложения.
как пользователь идентифицирован; что это один и тот же пользователь, который использует одно и то же приложение на разных устройствах.
Windows 10 делает смелый шаг вперед. Когда вы входите в Windows 10 с учетной записью Microsoft (MSA) или с корпоративной или (рабочей) учетной записью, предполагается, что –
-
У вас есть бесплатный доступ к учетной записи OneDrive для MSA, а также доступ к Active Directory (AD) и Azure Active Directory (AAD), который является облачной версией с вашей учетной записью предприятия.
-
У вас есть доступ к различным приложениям и ресурсам.
-
Устройства и приложения находятся в состоянии и настройках роуминга.
У вас есть бесплатный доступ к учетной записи OneDrive для MSA, а также доступ к Active Directory (AD) и Azure Active Directory (AAD), который является облачной версией с вашей учетной записью предприятия.
У вас есть доступ к различным приложениям и ресурсам.
Устройства и приложения находятся в состоянии и настройках роуминга.
Роуминг в Windows 10
Когда вы входите в ПК, вы устанавливаете некоторые настройки, такие как экран блокировки или цвет фона, или настраиваете различные типы настроек. Если у вас более одного компьютера или устройства под управлением Windows 10, ваши настройки и настройки на одном устройстве будут синхронизироваться из облака при входе на другие устройства с той же учетной записью.
В Windows 10, когда вы установили или персонализировали параметры приложения, эти параметры будут перемещаться с помощью API роуминга, доступных в UWP. Когда вы снова запустите то же приложение на другом устройстве, оно сначала получит настройки и применит эти настройки к приложению на этом устройстве.
Существует ограничение в 100 КБ для загрузки данных роуминга в облако. Если этот предел превышает, то синхронизация остановится и будет вести себя как локальная папка.
API-интерфейсы RoamingSettings представлены в виде словаря, в котором приложение может сохранять данные.
Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings; // Retrivve value from RoamingSettings var colorName = roamingSettings.Values["PreferredBgColor"].ToString(); // Set values to RoamingSettings roamingSettings.Values["PreferredBgColor"] = "Green";
Когда данные изменяются в RoamingSettings, они запускают событие DataChanged , где вы можете обновить свои настройки.
Windows.Storage.ApplicationData.Current.DataChanged += RoamingDataChanged; private void RoamingDataChanged(Windows.Storage.ApplicationData sender, object args) { // Something has changed in the roaming data or settings }
Давайте рассмотрим пример, в котором мы установим цвет фона приложения, и эти параметры будут перемещаться с помощью API роуминга, доступных в UWP.
Ниже приведен код XAML, в который добавлены различные элементы управления.
<Page x:Class = "RoamingSettingsDemo.Views.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:RoamingSettingsDemo.Views" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid x:Name = "MainGrid" Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height = "80" /> <RowDefinition /> </Grid.RowDefinitions> <StackPanel Orientation = "Horizontal" VerticalAlignment = "Top" Margin = "12,12,0,0"> <TextBlock Style = "{StaticResource HeaderTextBlockStyle}" FontSize = "24" Text = "Connected Experience Demo" /> </StackPanel> <Grid Grid.Row = "1" Margin = "0,80,0,0"> <StackPanel Margin = "62,0,0,0"> <TextBlock x:Name = "textBlock" HorizontalAlignment = "Left" TextWrapping = "Wrap" Text = "Choose your background color:" VerticalAlignment = "Top"/> <RadioButton x:Name = "BrownRadioButton" Content = "Brown" Checked = "radioButton_Checked" /> <RadioButton x:Name = "GrayRadioButton" Content = "Gray" Checked = "radioButton_Checked"/> </StackPanel> </Grid> </Grid> </Page>
Реализация C # для RoamingSettings и различных событий приведена ниже.
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // The RoamingSettingsDemo Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 namespace RoamingSettingsDemo.Views { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { SetBackgroundFromSettings(); Windows.Storage.ApplicationData.Current.DataChanged += RoamingDataChanged; } protected override void OnNavigatedFrom(NavigationEventArgs e) { Windows.Storage.ApplicationData.Current.DataChanged -= RoamingDataChanged; } private void RoamingDataChanged(Windows.Storage.ApplicationData sender, object args) { // Something has changed in the roaming data or settings var ignore = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () ⇒ SetBackgroundFromSettings()); } private void SetBackgroundFromSettings() { // Get the roaming settings Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings; if (roamingSettings.Values.ContainsKey("PreferBrownBgColor")) { var colorName = roamingSettings.Values["PreferBrownBgColor"].ToString(); if (colorName == "Gray") { MainGrid.Background = new SolidColorBrush(Colors.Gray); GrayRadioButton.IsChecked = true; } else if (colorName == "Brown") { MainGrid.Background = new SolidColorBrush(Colors.Brown); BrownRadioButton.IsChecked = true; } } } private void radioButton_Checked(object sender, RoutedEventArgs e){ if (GrayRadioButton.IsChecked.HasValue && (GrayRadioButton.IsChecked.Value == true)) { Windows.Storage.ApplicationData.Current.RoamingSettings. Values["PreferBrownBgCo lor"] = "Gray"; } else { Windows.Storage.ApplicationData.Current.RoamingSettings. Values["PreferBrownBgCo lor"] = "Brown"; } SetBackgroundFromSettings(); } } }
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
Давайте выберем серый цвет в качестве фона и закроем это приложение.
Теперь, когда вы запустите это приложение на этом или любом другом устройстве, вы увидите, что цвет фона изменился на серый. Это показывает, что приложение успешно извлекло информацию об изменении цвета фона в RoamingSettings .
Разработка Windows 10 – Навигация
В приложениях универсальной платформы Windows (UWP) навигация представляет собой гибкую модель структур навигации, элементов навигации и функций системного уровня. Он обеспечивает различные интуитивно понятные пользовательские интерфейсы для перемещения между приложениями, страницами и контентом.
Существуют некоторые ситуации и сценарии, когда весь контент и функциональные возможности легко помещаются на одной странице, и разработчикам не нужно создавать несколько страниц. Однако в большинстве приложений несколько страниц используются для взаимодействия между различным контентом и функциями.
Когда приложение имеет более одной страницы, для разработчиков очень важно обеспечить правильную навигацию.
Модели страниц
Как правило, в приложениях универсальной платформы Windows (UWP) используется одностраничная модель навигации.
Важные особенности –
-
Одностраничная модель навигации поддерживает весь контекст вашего приложения, а также дополнительный контент и данные в центральном фрейме.
-
Вы можете разделить содержимое вашего приложения на несколько страниц. Однако при переходе с одной страницы на другую ваше приложение загружает страницы в форму главной страницы.
-
Ни главная страница вашего приложения не выгружена, ни код и данные не выгружены, это облегчает управление состоянием и обеспечивает более плавную анимацию перехода между страницами.
Одностраничная модель навигации поддерживает весь контекст вашего приложения, а также дополнительный контент и данные в центральном фрейме.
Вы можете разделить содержимое вашего приложения на несколько страниц. Однако при переходе с одной страницы на другую ваше приложение загружает страницы в форму главной страницы.
Ни главная страница вашего приложения не выгружена, ни код и данные не выгружены, это облегчает управление состоянием и обеспечивает более плавную анимацию перехода между страницами.
Многостраничная навигация также используется для навигации между различными страницами или экранами, не беспокоясь о контексте приложения. В многостраничной навигации каждая страница имеет свой собственный набор функций, пользовательский интерфейс и данные и т. Д.
Многостраничная навигация обычно используется на веб-страницах внутри сайта.
Структура навигации
При многостраничной навигации каждая страница имеет свой собственный набор функций, пользовательский интерфейс, данные и т. Д. Например, приложение для обработки фотографий может иметь одну страницу для захвата фотографий, а затем, когда пользователь хочет редактировать фотографию, он переходит на другую страницу. и для поддержки библиотеки изображений у нее есть другая страница.
Структура навигации вашего приложения определяется тем, как организованы эти страницы.
Ниже приведены способы структурирования навигации в вашем приложении.
иерархия
В этом типе структуры навигации,
-
Страницы организованы в древовидную структуру.
-
Каждая дочерняя страница имеет только одного родителя, но родитель может иметь одну или несколько дочерних страниц.
-
Чтобы добраться до дочерней страницы, вы должны путешествовать через родителя.
Страницы организованы в древовидную структуру.
Каждая дочерняя страница имеет только одного родителя, но родитель может иметь одну или несколько дочерних страниц.
Чтобы добраться до дочерней страницы, вы должны путешествовать через родителя.
вглядываться
В этом типе навигации –
- Страницы существуют рядом.
- Вы можете переходить с одной страницы на другую в любом порядке.
В большинстве многостраничных приложений обе структуры используются одновременно. Некоторые страницы организованы как одноранговые, а некоторые организованы в иерархии.
Давайте возьмем пример, который содержит три страницы.
-
Создайте пустое приложение UWP с именем UWPNavigation .
-
Добавьте еще две пустые страницы, щелкнув правой кнопкой мыши проект в обозревателе решений и в меню выберите « Добавить»> «Новый элемент» , после чего откроется следующее диалоговое окно.
Создайте пустое приложение UWP с именем UWPNavigation .
Добавьте еще две пустые страницы, щелкнув правой кнопкой мыши проект в обозревателе решений и в меню выберите « Добавить»> «Новый элемент» , после чего откроется следующее диалоговое окно.
-
Выберите пустую страницу из средней панели и нажмите кнопку Добавить .
-
Теперь добавьте еще одну страницу, выполнив приведенные выше шаги.
Выберите пустую страницу из средней панели и нажмите кнопку Добавить .
Теперь добавьте еще одну страницу, выполнив приведенные выше шаги.
В обозревателе решений вы увидите три страницы – MainPage, BlankPage1 и BlankPage2 .
Ниже приведен код XAML для MainPage, в который добавлены две кнопки.
<Page x:Class = "UWPNavigation.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPNavigation" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub Header = "Hi, this Main Page"/> <Button Content = "Go to Page 1" Margin = "64,131,0,477" Click = "Button_Click"/> <Button Content = "Go to Page 2" Margin = "64,210,0,398" Click = "Button_Click_1"/> </Grid> </Page>
Ниже приведен код C # для двух кнопок на главной странице , которые будут перемещаться на две другие страницы.
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPNavigation { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e){ this.Frame.Navigate(typeof(BlankPage1)); } private void Button_Click_1(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(BlankPage2)); } } }
Код XAML для пустой страницы 1 показан ниже.
<Page x:Class = "UWPNavigation.BlankPage1" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPNavigation" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub Header = "Hi, this is page 1"/> <Button Content = "Go to Main Page" Margin = "64,94,0,514" Click = "Button_Click"/> </Grid> </Page>
Код C # для нажатия кнопки на пустой странице 1 , которая переместится на главную страницу, показана ниже.
using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 namespace UWPNavigation { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class BlankPage1 : Page { public BlankPage1() { this.InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(MainPage)); } } }
Ниже приведен код XAML для пустой страницы 2 .
<Page x:Class = "UWPNavigation.BlankPage2" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPNavigation" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Hub Header = "Hi, this is page 2"/> <Button Content = "Go to Main Page" Margin = "64,94,0,514" Click = "Button_Click"/> </Grid> </Page>
Ниже приведен код C # для события нажатия кнопки на пустой странице 2 , которая перейдет на главную страницу.
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 namespace UWPNavigation { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class BlankPage2 : Page { public BlankPage2(){ this.InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(MainPage)); } } }
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующее окно.
Когда вы нажимаете на любую кнопку, вы переходите на соответствующую страницу. Давайте нажмем Перейти на страницу 1, и будет отображена следующая страница.
Если вы нажмете кнопку «Перейти на главную страницу» , она вернется на главную страницу.
Разработка Windows 10 – Сеть
В настоящее время вы увидите много приложений, которые каким-то образом интегрированы с веб-службами или другими устройствами в сети. Получение онлайн-контента о погоде, последних новостей, чатов или одноранговых игр – вот некоторые примеры использования сетевых сервисов. Эти приложения создаются с использованием широкого спектра сетевых API. В Windows 10 сетевые API улучшены с точки зрения их скорости и производительности памяти, а также возможностей и гибкости, которые они предоставляют разработчикам.
возможности
Для работы в сети вы должны добавить соответствующие элементы возможностей в манифест приложения. Если в манифесте вашего приложения не указаны сетевые возможности, ваше приложение не будет иметь сетевых возможностей, и любая попытка подключиться к сети потерпит неудачу.
Ниже приведены наиболее часто используемые сетевые возможности.
S.No. | Возможность и описание |
---|---|
1 |
internetClient Предоставляет исходящий доступ к Интернету и сетям в общественных местах, таких как аэропорты и кафе. Большинство приложений, которым требуется доступ в Интернет, должны использовать эту возможность. |
2 |
internetClientServer Предоставляет приложению входящий и исходящий сетевой доступ из Интернета и сетей в общественных местах, таких как аэропорты и кафе. |
3 |
privateNetworkClientServer Предоставляет приложению входящий и исходящий доступ к сети в надежных местах пользователей, таких как дома и на работе. |
internetClient
Предоставляет исходящий доступ к Интернету и сетям в общественных местах, таких как аэропорты и кафе. Большинство приложений, которым требуется доступ в Интернет, должны использовать эту возможность.
internetClientServer
Предоставляет приложению входящий и исходящий сетевой доступ из Интернета и сетей в общественных местах, таких как аэропорты и кафе.
privateNetworkClientServer
Предоставляет приложению входящий и исходящий доступ к сети в надежных местах пользователей, таких как дома и на работе.
Чтобы определить одну или несколько возможностей в файле манифеста приложения, посмотрите на изображение, приведенное ниже.
Универсальная платформа Windows (UWP) содержит большой набор сетевых API, предназначенных для следующих целей:
- Запрос состояния подключения устройства и подключение к одноранговым устройствам.
- Связь с веб-сервисами REST и
- Загрузка больших медиа-файлов в фоновом режиме
Сетевые Технологии
В универсальной платформе Windows (UWP) разработчикам доступны следующие сетевые технологии, которые можно использовать в самых разных ситуациях.
Розетки
Сокеты используются, когда вы хотите установить связь с другим устройством по вашему собственному протоколу.
-
Вы можете использовать Windows.Networking.Sockets и Winsock для взаимодействия с другими устройствами в качестве разработчика приложения универсальной платформы Windows (UWP).
-
Windows.Networking.Sockets обладает тем преимуществом, что является современным API, разработанным для использования разработчиками UWP.
-
Если вы используете кроссплатформенные сетевые библиотеки или другой существующий код Winsock, используйте API Winsock .
Вы можете использовать Windows.Networking.Sockets и Winsock для взаимодействия с другими устройствами в качестве разработчика приложения универсальной платформы Windows (UWP).
Windows.Networking.Sockets обладает тем преимуществом, что является современным API, разработанным для использования разработчиками UWP.
Если вы используете кроссплатформенные сетевые библиотеки или другой существующий код Winsock, используйте API Winsock .
Следующий код показывает, как создать слушатель сокета.
try { //Create a StreamSocketListener to start listening for TCP connections. Windows.Networking.Sockets.StreamSocketListener socketListener = new Windows.Networking.Sockets.StreamSocketListener(); //Hook up an event handler to call when connections are received. socketListener.ConnectionReceived += SocketListener_ConnectionReceived; //Start listening for incoming TCP connections on the specified port. You can specify any port that's not currently in use. await socketListener.BindServiceNameAsync("1337"); } catch (Exception e) { //Handle exception. }
В следующем коде показана реализация обработчика событий SocketListener_ConnectionReceived .
private async void SocketListener_ConnectionReceived( Windows.Networking.Sockets.StreamSocketListen er sender, Windows.Networking.Sockets.StreamSocketListenerConnectionReceivedEventArgs args){ //Read line from the remote client. Stream inStream = args.Socket.InputStream.AsStreamForRead(); StreamReader reader = new StreamReader(inStream); string request = await reader.ReadLineAsync(); //Send the line back to the remote client. Stream outStream = args.Socket.OutputStream.AsStreamForWrite(); StreamWriter writer = new StreamWriter(outStream); await writer.WriteLineAsync(request); await writer.FlushAsync(); }
WebSocket
Протокол WebSockets обеспечивает быструю и безопасную двустороннюю связь между клиентом и сервером через Интернет. Разработчики универсальной платформы Windows (UWP) могут использовать классы MessageWebSocket и StreamWebSocket для подключения к серверам, поддерживающим протокол Websocket.
Важные особенности –
-
По протоколу WebSocket данные передаются немедленно через полнодуплексное соединение с одним сокетом.
-
Это позволяет отправлять и получать сообщения с обеих конечных точек в режиме реального времени.
-
WebSockets идеальны для использования в играх в реальном времени, где необходимо обеспечить безопасность мгновенных уведомлений в социальных сетях и актуальное отображение информации (игровой статистики) и использовать быструю передачу данных.
По протоколу WebSocket данные передаются немедленно через полнодуплексное соединение с одним сокетом.
Это позволяет отправлять и получать сообщения с обеих конечных точек в режиме реального времени.
WebSockets идеальны для использования в играх в реальном времени, где необходимо обеспечить безопасность мгновенных уведомлений в социальных сетях и актуальное отображение информации (игровой статистики) и использовать быструю передачу данных.
Следующий код показывает, как отправлять и получать сообщения по защищенному соединению.
MessageWebSocket webSock = new MessageWebSocket(); //In this case we will be sending/receiving a string so we need to set the MessageType to Utf8. webSock.Control.MessageType = SocketMessageType.Utf8; //Add the MessageReceived event handler. webSock.MessageReceived += WebSock_MessageReceived; //Add the Closed event handler. webSock.Closed += WebSock_Closed; Uri serverUri = new Uri("wss://echo.websocket.org"); try { //Connect to the server. await webSock.ConnectAsync(serverUri); //Send a message to the server. await WebSock_SendMessage(webSock, "Hello, world!"); } catch (Exception ex) { //Add code here to handle any exceptions }
Следующий код показывает реализацию события, которая получит строку от подключенного WebSocket .
//The MessageReceived event handler. private void WebSock_MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args){ DataReader messageReader = args.GetDataReader(); messageReader.UnicodeEncoding = UnicodeEncoding.Utf8; string messageString = messageReader.ReadString( messageReader.UnconsumedBufferLength); //Add code here to do something with the string that is received. }
HttpClient
API-интерфейсы пространств имен HttpClient и Windows.Web.Http предоставляют разработчику возможность отправлять и получать информацию с использованием протоколов HTTP 2.0 и HTTP 1.1.
Это может быть использовано для –
- общаться с веб-службой или веб-сервером.
- Загрузите или загрузите несколько небольших файлов.
- Поток контента по сети.
В следующем коде показано, как отправить запрос GET с помощью Windows.Web.Http.HttpClient и Windows.Web.Http.HttpResponseMessage .
//Create an HTTP client object Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient(); //Add a user-agent header to the GET request. var headers = httpClient.DefaultRequestHeaders; //The safe way to add a header value is to use the TryParseAdd method and verify the return value is true, //especially if the header value is coming from user input. string header = "ie"; if (!headers.UserAgent.TryParseAdd(header)) { throw new Exception("Invalid header value: " + header); } header = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"; if (!headers.UserAgent.TryParseAdd(header)) { throw new Exception("Invalid header value: " + header); } Uri requestUri = new Uri("http://www.contoso.com"); //Send the GET request asynchronously and retrieve the response as a string. Windows.Web.Http.HttpResponseMessage httpResponse = new Windows.Web.Http.HttpResponseMessage(); string httpResponseBody = ""; try { //Send the GET request httpResponse = await httpClient.GetAsync(requestUri); httpResponse.EnsureSuccessStatusCode(); httpResponseBody = await httpResponse.Content.ReadAsStringAsync(); } catch (Exception ex) { httpResponseBody = "Error: " + ex.HResult.ToString("X") + " Message: " + ex.Message; }
Разработка для Windows 10 – облачные сервисы
Как разработчик, вам могут потребоваться данные, отличные от доступных на вашем рабочем столе. Облачные сервисы могут помочь вам получить доступ к этим данным. Эта глава дает лучшее понимание облачных сервисов, которые могут вам потребоваться.
Microsoft предоставила платформу для облачных вычислений и инфраструктуру, известную как Microsoft Azure , где вы можете создавать, развертывать и управлять всеми приложениями и службами.
Azure был впервые выпущен 1 февраля 2010 года как Windows Azure. Позже он был переименован в Microsoft Azure 25 марта 2014 года.
Он предоставляет услуги как PaaS, так и IaaS, а также поддерживает множество различных языков программирования, инструментов и сред, включая как программное обеспечение и системы Microsoft, так и сторонних производителей.
Microsoft обновила облачные службы с помощью Windows 10. Интеграция учетных записей Microsoft была введена в Windows 8, хотя OneDrive существует с 2007 года. Для Windows 10 обе службы были обновлены с помощью расширенной интеграции и новых функциональных возможностей, которые привлекают больше пользователей.
Учетная запись Microsoft
Вы можете использовать облачные предложения Microsoft Azure со своей учетной записью Microsoft. Конечно, это не бесплатно, но вы можете использовать бесплатную 30-дневную пробную версию.
Когда вы впервые настраиваете компьютер с Windows 10 и входите в систему с учетной записью Microsoft, вы можете использовать ту же учетную запись для подписки Microsoft Azure. Чтобы зарегистрироваться в Microsoft Azure, нажмите здесь https://azure.microsoft.com/.
Подписавшись на Microsoft Azure, перейдите на портал Azure https://portal.azure.com/ . Вы увидите следующую страницу.
Вы можете хранить в базах данных, использовать виртуальные машины и т. Д. Вы также можете создавать и размещать серверную часть своего мобильного приложения.
Давайте попробуем это на примере, следуя приведенным ниже шагам.
-
Нажмите на опцию New на левой панели.
Нажмите на опцию New на левой панели.
-
Выберите « Web + Mobile»> «Мобильное приложение» и присвойте имя своему веб-приложению.
Выберите « Web + Mobile»> «Мобильное приложение» и присвойте имя своему веб-приложению.
-
Для отправки и развертывания приложения потребуется некоторое время. Как только этот процесс будет завершен, вы увидите следующую страницу. Здесь вы можете выбрать различные виды мобильных приложений, такие как Windows (C #), iOS Android и т. Д.
Для отправки и развертывания приложения потребуется некоторое время. Как только этот процесс будет завершен, вы увидите следующую страницу. Здесь вы можете выбрать различные виды мобильных приложений, такие как Windows (C #), iOS Android и т. Д.
-
Поскольку речь идет о Windows 10, выберите Windows (C #), которая откроет следующую страницу.
Поскольку речь идет о Windows 10, выберите Windows (C #), которая откроет следующую страницу.
-
Здесь вы можете увидеть два варианта загрузки. Это примеры проектов, которые вы можете просто загрузить и собрать в Visual Studio, а затем легко опубликовать в Microsoft Azure.
-
Давайте загрузим первый, который является серверным проектом. Это почтовый файл.
-
Когда загрузка будет завершена, разархивируйте ее и откройте в Visual Studio.
-
Теперь создайте это приложение. Если в списке есть какие-то ошибки, постройте его заново.
-
Запустите приложение. Вы увидите следующую веб-страницу, которая сейчас находится на localhost.
Здесь вы можете увидеть два варианта загрузки. Это примеры проектов, которые вы можете просто загрузить и собрать в Visual Studio, а затем легко опубликовать в Microsoft Azure.
Давайте загрузим первый, который является серверным проектом. Это почтовый файл.
Когда загрузка будет завершена, разархивируйте ее и откройте в Visual Studio.
Теперь создайте это приложение. Если в списке есть какие-то ошибки, постройте его заново.
Запустите приложение. Вы увидите следующую веб-страницу, которая сейчас находится на localhost.
-
Теперь, чтобы разместить это приложение в облаке, щелкните правой кнопкой мыши на опции Project в Solution Explore, как показано ниже.
Теперь, чтобы разместить это приложение в облаке, щелкните правой кнопкой мыши на опции Project в Solution Explore, как показано ниже.
-
Выберите опцию « Опубликовать» в меню. Вы увидите следующий диалог.
Выберите опцию « Опубликовать» в меню. Вы увидите следующий диалог.
-
Выберите первый вариант – Microsoft Azure Web Apps . Откроется следующее диалоговое окно.
Выберите первый вариант – Microsoft Azure Web Apps . Откроется следующее диалоговое окно.
-
Теперь нажмите на опцию Добавить учетную запись в меню, чтобы добавить учетную запись Microsoft Azure.
Теперь нажмите на опцию Добавить учетную запись в меню, чтобы добавить учетную запись Microsoft Azure.
-
Укажите свои учетные данные и нажмите Войти . Откроется следующее диалоговое окно.
-
После входа выберите приложение в меню « Существующие веб-приложения» и нажмите « ОК» .
Укажите свои учетные данные и нажмите Войти . Откроется следующее диалоговое окно.
После входа выберите приложение в меню « Существующие веб-приложения» и нажмите « ОК» .
-
Диалог, показанный ниже, отображает некоторую информацию, связанную с вашим приложением, такую как имя, имя сервера, URL и т. Д.
Диалог, показанный ниже, отображает некоторую информацию, связанную с вашим приложением, такую как имя, имя сервера, URL и т. Д.
-
Теперь нажмите на кнопку Проверить соединение . После проверки нажмите кнопку « Опубликовать» , и вы увидите, что ваше приложение теперь размещено в Microsoft Azure .
Теперь нажмите на кнопку Проверить соединение . После проверки нажмите кнопку « Опубликовать» , и вы увидите, что ваше приложение теперь размещено в Microsoft Azure .
Разработка для Windows 10 – Live Tiles
В этой главе мы поговорим о взаимодействии с пользователем с помощью тайлов. Это знаковая часть Windows 10. Плитки отображаются на экране « Пуск», а также в меню «Пуск» . Другими словами, это актив значка приложения, который появляется в различных формах в операционной системе Windows 10. Они являются визитными карточками для вашего приложения универсальной платформы Windows (UWP).
Плитка Анатомия
Есть три состояния плитки.
-
Базовое состояние – Основные компоненты стартовой плитки состоят из задней панели, значка и названия приложения.
Базовое состояние – Основные компоненты стартовой плитки состоят из задней панели, значка и названия приложения.
-
Полуживое состояние – это то же самое, что и базовый тайл, с той лишь разницей, что значок, который является числом, может отображать числа от 0 до 99.
Полуживое состояние – это то же самое, что и базовый тайл, с той лишь разницей, что значок, который является числом, может отображать числа от 0 до 99.
-
Текущее состояние – этот элемент содержит все элементы элемента состояния полуживого состояния, а также показывает дополнительную панель содержимого, в которую можно поместить все, что угодно, например фотографии, текст и т. Д.
Текущее состояние – этот элемент содержит все элементы элемента состояния полуживого состояния, а также показывает дополнительную панель содержимого, в которую можно поместить все, что угодно, например фотографии, текст и т. Д.
Обновление плитки
Существует четыре способа обновления тайлов.
-
Запланированный – Вы можете установить шаблон и время с ScheduledTileNotification .
-
Периодический – когда информация извлекается из URI, и вы можете указать время для извлечения информации после этого периода времени, например, 30 минут, 1 час, 6 часов. и т.п.
-
Local – Local можно обновить из вашего приложения; либо с переднего плана или фонового приложения.
-
Push – обновляется с сервера путем отправки информации с сервера.
Запланированный – Вы можете установить шаблон и время с ScheduledTileNotification .
Периодический – когда информация извлекается из URI, и вы можете указать время для извлечения информации после этого периода времени, например, 30 минут, 1 час, 6 часов. и т.п.
Local – Local можно обновить из вашего приложения; либо с переднего плана или фонового приложения.
Push – обновляется с сервера путем отправки информации с сервера.
Чтобы создать плитку, следуйте приведенному коду.
var tileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150Text01); var tileAttributes = tileXml.GetElementsByTagName("text"); tileAttributes[0].AppendChild(tileXml.CreateTextNode("Hello")); var tileNotification = new TileNotification(tileXml); TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);
Обновить значок довольно просто, потому что это просто число, и вы можете установить значение значка, как показано ниже.
var type = BadgeTemplateType.BadgeNumber; var xml = BadgeUpdateManager.GetTemplateContent(type); var elements = xml.GetElementsByTagName("badge"); var element = elements[0] as Windows.Data.Xml.Dom.XmlElement; element.SetAttribute("value", "7"); var updator = BadgeUpdateManager.CreateBadgeUpdaterForApplication(); var notification = new BadgeNotification(xml); updator.Update(notification);
Давайте создадим новый проект UWP в Visual Studio.
-
Вы увидите различные файлы png в папке Assets в обозревателе решений .
Вы увидите различные файлы png в папке Assets в обозревателе решений .
-
Давайте определим плитку по умолчанию и ее изображение в манифесте пакета.
-
Дважды щелкните файл package.appxmanifest . Откроется окно редактора манифеста.
-
Выберите вкладку Visual Assets .
Давайте определим плитку по умолчанию и ее изображение в манифесте пакета.
Дважды щелкните файл package.appxmanifest . Откроется окно редактора манифеста.
Выберите вкладку Visual Assets .
-
Вы можете выбрать изображения и значки для плитки вашего приложения с любым из указанных размеров. В разделе « Изображения и логотипы» для всех логотипов предусмотрены изображения по умолчанию.
- Квадратный Логотип 71х71
- Квадрат 150×150 Логотип
- Квадратный логотип 310×310
- Логотип магазина
-
Когда вы запустите свое приложение и перейдете на начальный экран, вы увидите плитку для своего приложения.
Вы можете выбрать изображения и значки для плитки вашего приложения с любым из указанных размеров. В разделе « Изображения и логотипы» для всех логотипов предусмотрены изображения по умолчанию.
Когда вы запустите свое приложение и перейдете на начальный экран, вы увидите плитку для своего приложения.
Разработка для Windows 10 – договор о разделе
В этой главе мы научимся обмениваться данными между приложениями. Пользователи часто сталкиваются с информацией, которой они рады поделиться с кем-то или использовать в другом приложении. В настоящее время пользователи хотят использовать технологии для связи и обмена с другими людьми.
Пользователь может захотеть поделиться –
- Связь с их социальной сетью
- Скопируйте картинку в отчет
- Загрузить файл в облачное хранилище
Сегодня приложениям необходимо обеспечить, чтобы используемые ими данные были также доступны пользователям для обмена и обмена. Share – это легкая функция, которую легко добавить в приложение UWP. У приложений есть несколько способов обмена данными с другими приложениями.
В приложениях UWP функция общего доступа может поддерживаться следующими способами;
-
Во-первых, приложение может быть исходным приложением, которое предоставляет контент, которым пользователь хочет поделиться.
-
Во-вторых, приложение может быть целевым приложением, которое пользователь выбирает в качестве места назначения для общего содержимого.
-
Приложение также может быть как исходным, так и целевым.
Во-первых, приложение может быть исходным приложением, которое предоставляет контент, которым пользователь хочет поделиться.
Во-вторых, приложение может быть целевым приложением, которое пользователь выбирает в качестве места назначения для общего содержимого.
Приложение также может быть как исходным, так и целевым.
Поделиться контентом
Обмен контентом из приложения, являющегося исходным приложением, очень прост. Для выполнения любой операции совместного использования вам понадобится объект класса DataPackage . Этот объект содержит данные, которыми пользователь хочет поделиться.
Следующие типы контента могут быть включены в объект DataPackage –
- Простой текст
- Унифицированные идентификаторы ресурса (URI)
- HTML
- Форматированный текст
- Bitmaps
- файлы
- Данные, определенные разработчиком
При совместном использовании данных вы можете включить один или несколько из вышеупомянутых форматов. Чтобы поддержать совместное использование в вашем приложении, вам сначала нужно получить экземпляр класса DataTransferManager .
Затем он зарегистрирует обработчик события, который вызывается всякий раз, когда происходит событие DataRequested .
DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView(); dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(this.ShareTextHandler);
Когда ваше приложение получает объект DataRequest , тогда ваше приложение готово добавить контент, которым пользователь хочет поделиться.
private void ShareTextHandler(DataTransferManager sender, DataRequestedEventArgs e){ DataRequest request = e.Request; // The Title is mandatory request.Data.Properties.Title = "Share Text Example"; request.Data.Properties.Description = "A demonstration that shows how to share text."; request.Data.SetText("Hello World!"); }
Любое содержимое, которое разделяет ваше приложение, должно содержать два свойства:
- Свойство Title, которое является обязательным и должно быть установлено.
- Сам контент.
Получение общего контента
Если вы хотите, чтобы ваше приложение могло получать общий контент, то первое, что вам нужно сделать, это объявить, что оно поддерживает Контракт на совместное использование . После объявления система позволит вашему приложению быть доступным для получения контента.
Чтобы добавить поддержку контракта на акции –
-
Дважды щелкните файл package.appmanifest .
-
Перейдите на вкладку « Объявления ». Выберите « Поделиться целью» в списке « Доступные объявления» и нажмите кнопку « Добавить» .
Дважды щелкните файл package.appmanifest .
Перейдите на вкладку « Объявления ». Выберите « Поделиться целью» в списке « Доступные объявления» и нажмите кнопку « Добавить» .
-
Если вы хотите, чтобы ваше приложение получало файлы любого типа в качестве общего содержимого, вы можете указать типы файлов и форматы данных.
-
Чтобы указать поддерживаемые форматы данных, перейдите в раздел « Форматы данных » на странице « Объявления» и нажмите « Добавить новый» .
-
Введите название формата данных, который вы поддерживаете. Например, «Текст» .
-
Чтобы указать тип поддерживаемого файла , в разделе « Поддерживаемые типы файлов » на странице « Объявления» нажмите « Добавить новый» .
-
Введите расширение имени файла, которое вы хотите поддерживать, например, .pdf
-
Если вы хотите поддерживать все типы файлов , установите флажок SupportsAnyFileType .
Если вы хотите, чтобы ваше приложение получало файлы любого типа в качестве общего содержимого, вы можете указать типы файлов и форматы данных.
Чтобы указать поддерживаемые форматы данных, перейдите в раздел « Форматы данных » на странице « Объявления» и нажмите « Добавить новый» .
Введите название формата данных, который вы поддерживаете. Например, «Текст» .
Чтобы указать тип поддерживаемого файла , в разделе « Поддерживаемые типы файлов » на странице « Объявления» нажмите « Добавить новый» .
Введите расширение имени файла, которое вы хотите поддерживать, например, .pdf
Если вы хотите поддерживать все типы файлов , установите флажок SupportsAnyFileType .
-
Когда пользователь выбирает ваше приложение в качестве целевого приложения для обмена данными, возникает событие OnShareTargetActivation .
-
Ваше приложение должно обработать это событие для обработки данных, которыми пользователь хочет поделиться.
Когда пользователь выбирает ваше приложение в качестве целевого приложения для обмена данными, возникает событие OnShareTargetActivation .
Ваше приложение должно обработать это событие для обработки данных, которыми пользователь хочет поделиться.
protected override async void OnShareTargetActivated(ShareTargetActivatedEventArgs args) { // Code to handle activation goes here. }
-
Все данные, которыми пользователь хочет поделиться с любым приложением, содержатся в объекте ShareOperation . Вы также можете проверить формат данных, которые он содержит.
Все данные, которыми пользователь хочет поделиться с любым приложением, содержатся в объекте ShareOperation . Вы также можете проверить формат данных, которые он содержит.
Ниже приведен фрагмент кода, который обрабатывает общий контент в текстовом формате.
ShareOperation shareOperation = args.ShareOperation; if (shareOperation.Data.Contains(StandardDataFormats.Text)) { string text = await shareOperation.Data.GetTextAsync(); // To output the text from this example, you need a TextBlock control // with a name of "sharedContent". sharedContent.Text = "Text: " + text; }
Давайте посмотрим на простой пример, создав новый проект UWP, который поделится веб-ссылкой.
Ниже приведен код XAML, в котором создается кнопка с некоторыми свойствами.
<Page x:Class = "UWPSharingDemo.MainPage" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "using:UWPSharingDemo" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <Grid Background = "{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Orientation = "Vertical"> <TextBlock Text = "Share Web Link" Style = "{StaticResource HeaderTextBlockStyle}" Margin = "30"></TextBlock> <Button Content = "Invoke share contract" Margin = "10" Name = "InvokeShareContractButton" Click = "InvokeShareContractButton_Click" ></Button> </StackPanel> </Grid> </Page>
Код C #, в котором реализовано событие нажатия кнопки, и код совместного использования URI приведен ниже.
using System; using Windows.ApplicationModel.DataTransfer; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 namespace UWPSharingDemo { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { DataTransferManager dataTransferManager; public MainPage() { this.InitializeComponent(); dataTransferManager = DataTransferManager.GetForCurrentView(); dataTransferManager.DataRequested += dataTransferManager_DataRequested; } void dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { Uri sharedWebLink = new Uri("https://msdn.microsoft.com"); if (sharedWebLink != null) { DataPackage dataPackage = args.Request.Data; dataPackage.Properties.Title = "Sharing MSDN link"; dataPackage.Properties.Description = "The Microsoft Developer Network (MSDN) is designed to help developers write applications using Microsoft products and technologies."; dataPackage.SetWebLink(sharedWebLink); } } private void InvokeShareContractButton_Click(object sender, RoutedEventArgs e) { DataTransferManager.ShowShareUI(); } } }
Когда приведенный выше код скомпилирован и выполнен, вы увидите следующую страницу в эмуляторе.
Когда кнопка нажата, она предоставит возможность поделиться тем, какое приложение.
Нажмите на сообщение, и появится следующее окно, откуда вы можете отправить ссылку любому.
Windows 10 Dev – Портирование на Windows
В этой главе мы узнаем, как перенести существующее приложение Windows 8.1 приложения на универсальную платформу Windows (UWP). Вы можете создать один пакет приложений для Windows 10, который ваши клиенты смогут установить на все типы устройств.
После портирования вашего приложения на Windows 10 UWP ваше приложение получит следующие преимущества:
- Захватывающее новое оборудование
- Большие возможности монетизации
- Современный набор API,
- Адаптивный контроль пользовательского интерфейса,
- Адаптивный дизайн и код
- Диапазон способов ввода, таких как мышь, клавиатура, сенсорный ввод и речь.
Портирование проекта Windows 8.x в проект UWP
Существует два варианта переноса существующего приложения Windows 8.x на универсальную платформу Windows (UWP).
Вариант 1. Один – создать новый проект Windows 10 в Visual Studio и скопировать в него свои файлы.
Вариант 2. Другой вариант – отредактировать копию существующих файлов проекта, включая манифест пакета приложения.
Ниже приведены основные шаги при использовании первого варианта.
-
Запустите Microsoft Visual Studio 2015 и создайте новый проект «Пустое приложение» (Windows Universal) с именем UWPBookStore .
-
Ваш новый проект создает пакет приложения (файл appx), который будет работать на всех семействах устройств.
-
В своем проекте приложения Universal 8.1 определите все файлы исходного кода и файлы визуальных ресурсов, которые вы хотите использовать повторно. Ниже показан пример приложения, в котором есть три проекта. Один используется для Windows, второй для мобильных устройств, а третий – общий проект для Windows и мобильных устройств.
-
После запуска этого приложения на телефоне вы увидите следующее окно.
Запустите Microsoft Visual Studio 2015 и создайте новый проект «Пустое приложение» (Windows Universal) с именем UWPBookStore .
Ваш новый проект создает пакет приложения (файл appx), который будет работать на всех семействах устройств.
В своем проекте приложения Universal 8.1 определите все файлы исходного кода и файлы визуальных ресурсов, которые вы хотите использовать повторно. Ниже показан пример приложения, в котором есть три проекта. Один используется для Windows, второй для мобильных устройств, а третий – общий проект для Windows и мобильных устройств.
После запуска этого приложения на телефоне вы увидите следующее окно.
-
После запуска оконного приложения вы увидите следующее приложение.
После запуска оконного приложения вы увидите следующее приложение.
- Теперь откройте только что созданное приложение проекта UWP
-
Из общего проекта скопируйте папку Assets CoverImages, содержащую файлы изображений обложки книги (.png). Также скопируйте папку ViewModel и MainPage.xaml и замените файл в месте назначения.
-
Из проекта Windows скопируйте BookstoreStyles.xaml . Все ключи ресурсов в этом файле разрешаются в приложении Windows 10. Некоторые из тех в эквивалентном файле WindowsPhone не будут.
-
В обозревателе решений убедитесь, что параметр « Показать все файлы» включен .
Из общего проекта скопируйте папку Assets CoverImages, содержащую файлы изображений обложки книги (.png). Также скопируйте папку ViewModel и MainPage.xaml и замените файл в месте назначения.
Из проекта Windows скопируйте BookstoreStyles.xaml . Все ключи ресурсов в этом файле разрешаются в приложении Windows 10. Некоторые из тех в эквивалентном файле WindowsPhone не будут.
В обозревателе решений убедитесь, что параметр « Показать все файлы» включен .
-
Выберите файлы, которые вы скопировали, щелкните их правой кнопкой мыши и выберите « Включить в проект», как показано ниже.
Выберите файлы, которые вы скопировали, щелкните их правой кнопкой мыши и выберите « Включить в проект», как показано ниже.
-
Это будет автоматически включать их содержащие папки. Затем вы можете переключить Show All Files ‘OFF’, если хотите.
-
Теперь структура вашего проекта будет выглядеть в обозревателе решений .
Это будет автоматически включать их содержащие папки. Затем вы можете переключить Show All Files ‘OFF’, если хотите.
Теперь структура вашего проекта будет выглядеть в обозревателе решений .
-
Отредактируйте только что скопированный исходный код и файлы разметки и измените все ссылки на пространство имен Bookstore1_81 на пространство имен UWPBookStore .
-
Самый простой способ – заменить пространство имен функцией « Заменить в файлах» . Никаких изменений кода не требуется в модели представления.
-
Теперь, когда приведенный выше код выполняется, вы можете запустить его как на локальной машине, так и на мобильном телефоне, как показано ниже.
Отредактируйте только что скопированный исходный код и файлы разметки и измените все ссылки на пространство имен Bookstore1_81 на пространство имен UWPBookStore .
Самый простой способ – заменить пространство имен функцией « Заменить в файлах» . Никаких изменений кода не требуется в модели представления.
Теперь, когда приведенный выше код выполняется, вы можете запустить его как на локальной машине, так и на мобильном телефоне, как показано ниже.
Теперь второй вариант – отредактировать копию существующих файлов проекта, включая манифест пакета приложения. Файл проекта и файл package.appmanifest нуждаются в некоторых изменениях при портировании с Windows / phone 8.x на Windows 10.
Microsoft предоставила утилиту обновления проекта UWP, которая очень полезна при переносе существующего приложения. Утилиту можно скачать с github.com .
Мы рекомендуем вам следовать приведенным выше примерам шаг за шагом для лучшего понимания.
Обзор
Собственная реклама — это компонентно-ориентированное объявление, которое позволяет издателям гибко размещать отдельные компоненты текста: название, изображение, логотип, описание, призыв к действию — чтобы обеспечить наилучшее дополнение к внешнему виду остальной части приложения. Это позволяет разработчикам самостоятельно использовать шрифты, цвета и анимации для создания ненавязчивого пользовательского интерфейса в своем приложении, в то же время получая высокую доходность от рекламы. Для рекламодателей это также обеспечивает высокоэффективные места размещения, поскольку реклама встроена в приложение, и пользователи склонны больше взаимодействовать с этим спонсируемым контентом. Согласно отчету Mobile Marketing, собственная реклама в приложении обычно получает в пять раз больше пользовательского охвата, чем традиционные баннерные объявления, и, следовательно, получает больше средств от рекламодателей (в соответствии с eMarketer и другими отчетами).
Начиная с этого момента разработчики могут создавать собственные места для рекламы в своих приложениях или играх, используя последнюю версию Microsoft Advertising SDK (10.0.4 или новее). Платформа Microsoft Monetization предоставляет разработчикам максимальную свободу для создания собственных презентаций и доступна ограниченному набору издателей в закрытом экспериментальном проекте. Для доступа к проекту напишите по адерсу aiacare@microsoft.com.
С чего начать?
Как и прежде, начните с загрузки Microsoft Advertising SDK. Это предоставит вам библиотеки для включения собственных объявлений в ваше приложение или игру.
Создайте «Собственный» рекламный блок для своего приложения в разделе «Монетизация с рекламой» в DevCenter (dev.windows.com). Этот рекламный блок вы будете использовать в своем приложении, когда вы запрашиваете объявление в коде.
Как добавить встроенные объявления в свое приложение?
В этом разделе предполагается, что вы знакомы с Microsoft Advertising SDK для вашего UWP приложения или игры. Если вы еще не работали с этим, ознакомтесь с инстукцией для начала работы.
Чтобы показать собственные объявления в вашем приложении, следуйте инструкциям по типу проекта:
XAML/.NET
HTML/JavaScript
XAML/.NET
В этом разделе приведены примеры C# для вашего проекта XAML/.NET. Вам следует пройти эти простые шаги, чтобы получить собственные объявления в вашем коде.
Шаг 1: Ссылки на установку
Откройте проект в Visual Studio. В диспетчере ссылок (Reference Manager) разверните раздел Universal Windows, нажмите «Расширения», а затем установите флажок рядом с Microsoft Advertising SDK для XAML.
using Microsoft.Advertising.WinRT.UI;
Шаг 2. Настройка управления для собственных объявлений
В соответствующем месте в вашем приложении (например, в MainPage или на другой странице) укажите объект NativeAdsManager и строковые поля, которые представляют идентификатор приложения и идентификатор рекламного блока для вашего собственного объявления. В следующем примере кода присваиваются поля myAppId и myAdUnitId с тестовыми значениями для собственных объявлений, предоставляемых в значениях тестового режима. Эти значения используются только для тестирования; Вы должны заменить их существующеми значениями из Windows DevCenter, прежде чем публиковать свое приложение.
NativeAdsManager nativeAdsManager = null; string appId = "d25517cb-12d4-4699-8bdc-52040c712cab"; string adUnitId = "test";
В коде, который запускается при запуске, создайте экземпляр NativeAdsManager.
// Ad Events nativeAdsManager = new NativeAdsManager(appId, adUnitId);
Шаг 3: Запрос объявления
Если вы хотите показывать объявление, необходимо отправить запрос с помощью NativeAdsManager и подключить события.
nativeAdsManager.RequestAd(); nativeAdsManager.AdReady += NativeAd_OnAdReady; nativeAdsManager.ErrorOccurred += NativeAd_ErrorOccurred;
Шаг 4: Использование компонентов объявления для создания опыта
Предположим, у вас есть страница XAML, в которой есть разные шаблоны для заголовка, описания, спонсирования, призыва к действию объявления и хранилища, который содержит все эти элементы. Пример StackPanel, содержащий все элементы.
Основываясь на компонентах объявления, которые вы хотите добавить в ваше приложение, ваш код может отличаться. Вот пример прослушивателя событий OnAdReady, в котором используются Название, Описание, Призыв к Действию и Изображение.
void NativeAd_OnAdReady(object sender, object e) { NativeAd nativeAd = (NativeAd)e; TitleBox.Text = nativeAd.Title; //if description is not null show description textbox var description = nativeAd.Description; if (!string.IsNullOrEmpty(description)) { DescriptionBox.Text = nativeAd.Description; DescriptionBox.Visibility = Visibility.Visible; } //if sponsoredBy is not null show sponsoredBy textbox var sponsoredBy = nativeAd.SponsoredBy; if (!string.IsNullOrEmpty(sponsoredBy)) { SponsoredBy.Text = sponsoredBy; SponsoredBy.Visibility = Visibility.Visible; } //if CallToAction is not null update Button var callToAction = nativeAd.CallToAction; if (!string.IsNullOrEmpty(callToAction)) { CallToAction.Content = callToAction; CallToAction.Visibility = Visibility.Visible; } // Assets consists further information about Ad var assets = nativeAd.AdditionalAssets; // Loading images var icon = nativeAd.IconImage; if (icon != null) { var bitmapImage = new BitmapImage(); bitmapImage.UriSource = new Uri(nativeAd.IconImage.Url); IconImage.Source = bitmapImage; // Best view when using the Height and Width of the image given IconImage.Height = nativeAd.IconImage.Height; IconImage.Width = nativeAd.IconImage.Width; IconImageContainer.Visibility = Visibility.Visible; } // There might be multiple main images sent by the server var mainImages = nativeAd.MainImages; if (mainImages.Count > 0) { var mainImage = mainImages[0]; var bitmapImage = new BitmapImage(); bitmapImage.UriSource = new Uri(mainImage.Url); MainImage.Source = bitmapImage; // Best view when using the Height and Width of the image given MainImage.Height = mainImage.Height; MainImage.Width = mainImage.Width; MainImageContainer.Visibility = Visibility.Visible; } // It is required to show the AdIcon in your container NativeAdContainer.Children.Add(nativeAd.AdIcon); // Register any xaml framework element for clicks/impressions nativeAd.RegisterAdContainer(NativeAdContainer);
P.S: Разработчик должен «Регистрировать» контейнер для объявлений XAML (любой элемент структуры) с объектом Native Ads. Это необходимо для обработки показов и отслеживания кликов и имеет решающее значение для рекламы. Несоблюдение этого требования может привести к блокировке рекламных блоков и рекламных выплат Microsoft.
HTML/JavaScript
Подробная информация о функции HTML появится в ближайшее время! Пожалуйста, свяжитесь с нами (aiacare@microsoft.com), если ваши приложения находятся в формате HTML/JS, и вам необходима эта функция.
Методические рекомендации
Несмотря на то, что разработчик имеет полный контроль над тем, как создавать рекламные ролики и какие компоненты объявления отображаются пользователю, объявление рекламодателя должно получить сообщение от пользователя. Существует прекрасный баланс, который необходимо достичь, чтобы получить максимальную ценность от собственного объявления.
Вот некоторые рекомендации по обеспечению баланса.
Требуется показать
Существует два актива рекламодателя, которые всегда должны отображаться пользователю в дизайне собственного объявления. Отказ добавления любого из них может привести к низкой производительности вашего рекламного блока и возможно низкой (или отсутствующей) доходности. Этими активами являются:
- Название объявления
- Изначальная иконка объявления (эта иконка объявления отправляется как часть объекта NativeAd — свойство с именем AdIcon) или «Спонсировано» или же такие тексты, как «Спонсируемый», «Повышенный», «Рекомендованный»
Несоблюдение этих рекомендаций может привести к удалению adUnits из рекламной системы.
Рекламный опыт
Ваше собственное объявление должно быть четко очерчено от остальной части вашего контента и иметь пространство вокруг него, чтобы предотвратить случайные клики. Используйте границу, фоновое изображение или другую обработку для отделения содержимого объявления. Всегда помните, что случайные клики пользователя на ваше объявление не выгодны в долгосрочной перспективе дохода от ваших объявлений и для удовлетворения конечных пользователей.
Вы всегда должны показывать различимый значок «Объявления» для просмотра данного объявления. По возможности покажите поле «Спонсированные», чтобы четко указать, что контент является объявлением и предоставлен рекламодателем.
Требования к отображению текста
Собственные объявления всегда должны отображать название. Предоставьте достаточное пространство для отображения не менее 25 символов названия. Если название длиннее нормы, замените дополнительный текст на многоточие.
Убедитесь, что Call-to-Action (призыв к действию) отделен от остальной рекламной информации рекламодателя.
Если вы выберете оставшуюся часть рекламного текста (описание) из ответа объявления, укажите место для отображения не менее 75 символов. Лучше всего использовать анимацию, чтобы показать полный контент описания объявления.
Призыв к действию (Call-to-Action)
В собственных объявлениях всегда должен отображаться призыв к действию, который показывает пользователю, что объявление кликабельное по кнопке или гиперссылке.
Строка CTA (Call-to-Action) всегда должна отображаться польностью, так как она является решающим компонентом объявления рекламодателя.
Изучайте и оптимизируйте
Рекомендуется, создавать и использовать разные рекламные блоки для каждого отдельного размещения собственных объявлений в приложении. Это позволяет создавать отчеты и обучение для каждого места размещения, которое затем можно использовать для оптимизации каждого места отдельно, до достижения оптимальной производительности.
В случае каких-либо дополнительных вопросов, пожалуйста, обратитесь к aiacare@microsoft.com, и мы будем рады вам помочь.
Официальный анонс возможностей рекламы.
I’ve been doing some digging lately on my system in trying to get an overview of everything that runs or is installed on my system. I’m almost done, but the components/apps in the list below I can’t exactly figure out what their purposes are. I hope someone would be so kind to lend me a helping hand in getting this stuff mapped out.
-
Microsoft.AAD.BrokerPlugin <— I believe AAD stands for Azure Active Directory, but I’m not sure what the plugin is brokering for.
-
Microsoft.AccountsControl <— Is it related to the UAC prompt or managing of admin privileges in general?
-
Microsoft.Advertising.Xaml <— Does this app relate to displaying advertisements in Store apps?
-
Microsoft.Windows.Apprep.ChxApp <— Should I call this Apprep ChxApp? Or just ChxApp? Also what do the Apprep and ChxApp abbreviations mean? Is this basically SmartScreen?
-
Microsoft.Windows.AssignedAccessLockApp <— Is Assigned Access Lockapp basically just the lockscreen? And if so, does it have a relation with Windows Hello and Cortana?
-
Microsoft.Windows.ContentDeliveryManager <— I’ve read that Content Delivery Manager is responsible for Windows Spotlight stuff, app suggestions and silent installs of advertised apps. Does Content Delivery Manager have an other function as well?
-
Microsoft.BioEnrollment <— Is this a tool to login with Windows Hello biometric authentication, or just a tool to set up biometric authentication? Or is it both, or something else?
-
Microsoft.PPIProjection <— What does PPI stand for, and what does it project?
-
Windows.PrintDialog <— What is this? It clearly pertains to printing, but I don’t know in what sense.
-
Microsoft.Windows.SecondaryTileExperience <— What is Secondary Tile Experience? I assume it has got something to do with the Start Menu (could be wrong), but why is it called **Secondary* Tile Experience in that case?
-
Secure Assessment Browser <— What exactly is this? What’s its purpose?
-
Microsoft.XboxGameCallableUI <— What is this? What’s its purpose in relation to the Xbox or Xboxs apps on Windows 10?
Удаление встроенных приложений Appx в Windows 10
Манипулировать встроенными приложениями Windows 10 можно с помощью PowerShell.
Чтобы получить список приложений, установленных в системе выполним:
Get-AppxPackage -AllUsers | Select Name, PackageFullName
Чтобы удалить установленные приложения для всех пользователей системы:
Get-AppxPackage Microsoft.Windows.ParentalControls | Remove-AppxPackage Get-AppxPackage Windows.ContactSupport | Remove-AppxPackage Get-AppxPackage Microsoft.Xbox* | Remove-AppxPackage Get-AppxPackage microsoft.windowscommunicationsapps | Remove-AppxPackage # Mail and Calendar Get-AppxPackage Microsoft.Windows.Photos | Remove-AppxPackage Get-AppxPackage Microsoft.WindowsCamera | Remove-AppxPackage Get-AppxPackage Microsoft.SkypeApp | Remove-AppxPackage Get-AppxPackage Microsoft.Zune* | Remove-AppxPackage Get-AppxPackage Microsoft.WindowsPhone | Remove-AppxPackage # Phone Companion Get-AppxPackage Microsoft.WindowsMaps | Remove-AppxPackage Get-AppxPackage Microsoft.Office.OneNote | Remove-AppxPackage Get-AppxPackage Microsoft.Office.Sway | Remove-AppxPackage Get-AppxPackage Microsoft.Appconnector | Remove-AppxPackage Get-AppxPackage Microsoft.WindowsFeedback* | Remove-AppxPackage Get-AppxPackage Microsoft.Windows.FeatureOnDemand.InsiderHub | Remove-AppxPackage Get-AppxPackage Microsoft.Windows.Cortana | Remove-AppxPackage Get-AppxPackage Microsoft.People | Remove-AppxPackage Get-AppxPackage Microsoft.Bing* | Remove-AppxPackage # Money, Sports, News, Finance and Weather Get-AppxPackage Microsoft.Getstarted | Remove-AppxPackage Get-AppxPackage Microsoft.MicrosoftOfficeHub | Remove-AppxPackage Get-AppxPackage Microsoft.MicrosoftSolitaireCollection | Remove-AppxPackage Get-AppxPackage Microsoft.WindowsSoundRecorder | Remove-AppxPackage Get-AppxPackage Microsoft.3DBuilder | Remove-AppxPackage Get-AppxPackage Microsoft.Messaging | Remove-AppxPackage Get-AppxPackage Microsoft.CommsPhone | Remove-AppxPackage Get-AppxPackage Microsoft.Advertising.Xaml | Remove-AppxPackage Get-AppxPackage Microsoft.Windows.SecondaryTileExperience | Remove-AppxPackage Get-AppxPackage Microsoft.Windows.ParentalControls | Remove-AppxPackage Get-AppxPackage Microsoft.Windows.ContentDeliveryManager | Remove-AppxPackage Get-AppxPackage Microsoft.Windows.CloudExperienceHost | Remove-AppxPackage Get-AppxPackage Microsoft.Windows.ShellExperienceHost | Remove-AppxPackage Get-AppxPackage Microsoft.BioEnrollment | Remove-AppxPackage Get-AppxPackage Microsoft.OneConnect | Remove-AppxPackage Get-AppxPackage *Twitter* | Remove-AppxPackage Get-AppxPackage king.com.CandyCrushSodaSaga | Remove-AppxPackage Get-AppxPackage flaregamesGmbH.RoyalRevolt2 | Remove-AppxPackage Get-AppxPackage *Netflix | Remove-AppxPackage Get-AppxPackage Facebook.Facebook | Remove-AppxPackage Get-AppxPackage Microsoft.MinecraftUWP | Remove-AppxPackage Get-AppxPackage *MarchofEmpires | Remove-AppxPackage
Если нужно вернуть удалённые приложения из конфигурации «по умолчанию»:
Get-AppxPackage –AllUsers | ` Foreach {Add-AppxPackage -DisableDevelopmentMode ` -Register "$($_.InstallLocation)AppXManifest.xml"}
Если нужно вернуть конкретное приложение, например «Погода»:
Get-AppXPackage –AllUsers -Name Microsoft.BingWeather | ` Foreach {Add-AppxPackage -DisableDevelopmentMode ` -Register "$($_.InstallLocation)AppXManifest.xml"}
Дополнительные источники информации:
Проверено на следующих конфигурациях:
Автор публикации:
Алексей Максимов
Время публикации: 04.02.2018 09:57