Русский
Русский
English
Статистика
Реклама

Windows 10 sophia script

Закрепляем ярлыки на начальном экране в Windows 10 у текущего пользователя

06.04.2021 10:06:21 | Автор: admin

Эта статья своего рода proof of concept, как можно закрепить программно (открепить) ярлык на начальном экране для текущего пользователя без перезапуска или выхода из учетной записи. Как вы знаете, с выходом Windows 10 October 2018 Microsoft без шума закрыл доступ к API открепления (закрепления) ярлыков от начального экрана и панели задач: отныне это можно сделать лишь вручную.

Ниже приведен пример кода для закрепления (открепления) ярлыка на начальный экран, который когда-то работал. Как можете видеть, в коде используется метод получения локализорованной строки, и для этого нам необходимо знать код строки, чтобы вызвать соответствующий пункт контекстного меню. В данном пример, чтобы закрепить ярлык командной строки, мы вызываем строку с кодом 51201, Закрепить на начальном экране, из библиотеки %SystemRoot%\system32\shell32.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:APPDATA\Microsoft\Windows\Start Menu\Programs\System Tools\Command 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, конечно, отдает глагол контекстного меню Закрепить на начальном &экране, но не может его выполнить.

Где-то читал, что, возможно, Microsoft заблокировал доступ в целях недопущения закрепления ярлыков bloatware. Звучит странно, но ладно

Я уже много лет поддерживаю крупнейший PowerShell-модуль для тонкой настройки Windows 10 и автоматизации рутинных задач. Подробнее можно почитать здесь. И встала задача из спортивного интереса обойти это ограничение и попробовать закрепить нужные мне ярлыки. Речь, конечно, идет по большей части о домашних пользователях, ведь в энтерпрайзе используется GPO для импорта предзаготовленного макета начального экрана и панели задач.

Мы знаем, что текущий макет начального экрана можно выгрузить в формате XML. Но даже, если его настроить должным образом, импортировать макет в профиль текущего пользователя не получится: Import-StartLayout -LayoutPath "D:\Layout.xml импортирует макеты начального экрана и панели задач только для новых пользователей.

Идея заключается в том, чтобы использовать политику Макет начального экрана (Prevent users from customizing their Start Screen), отвечающую за подгрузку предзаготовленного макета в формате XML из определенного места. Соответственно, наш хак будет состоять из следующих пунктов:

  • Выгружаем текущий макет начального экрана;

  • Парсим XML, добавляя необходимые нам ярлыки (ссылки должны вести на реально существующие ярлыки) и сохраняем;

  • С помощью политики временно выключаем возможность редактировать макет начального экрана;

  • Перезапускаем меню Пуск;

  • Программно открываем меню Пуск, чтобы в реестре сохранился его макет;

  • Выключаем политику, чтобы можно было редактировать макет начального экрана;

  • И открываем меню Пуск опять.

Вуаля! В данном примере мы настроили начальный экран на лету, закрепив на него три ярлыка: Панель управления, устройства и принтеры и PowerShell.

<#.SYNOPSISConfigure the Start tiles.PARAMETER ControlPanelPin the "Control Panel" shortcut to Start.PARAMETER DevicesPrintersPin the "Devices & Printers" shortcut to Start.PARAMETER PowerShellPin the "Windows PowerShell" shortcut to Start.PARAMETER UnpinAllUnpin 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.LINKhttps://github.com/farag2/Windows-10-Sophia-Script.NOTESSeparate arguments with commaCurrent user#>[CmdletBinding()]param([Parameter(Mandatory = $false,Position = 0)][switch]$UnpinAll,[Parameter(Mandatory = $false,Position = 1)][ValidateSet("ControlPanel", "DevicesPrinters", "PowerShell")][string[]]$Tiles,[string]$StartLayout = "$PSScriptRoot\StartLayout.xml")begin{# Unpin all the Start tilesif ($UnpinAll){Export-StartLayout -Path $StartLayout -UseDesktopApplicationID[xml]$XML = Get-Content -Path $StartLayout -Encoding UTF8 -Force$Groups = $XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.Groupforeach ($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 PanelName = "ControlPanel"Size = "2x2"Column = 0Row = 0AppID = "Microsoft.Windows.ControlPanel"},# "Devices & Printers" hash table@{# Special name for "Devices & Printers"Name = "DevicesPrinters"Size   = "2x2"Column = 2Row    = 0AppID  = $Script:DevicesPrintersAppID},# Windows PowerShell hash table@{# Special name for Windows PowerShellName = "PowerShell"Size = "2x2"Column = 4Row = 0AppID = "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.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 XMLfunction 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 layoutExport-StartLayout -Path $StartLayout -UseDesktopApplicationID}[xml]$XML = Get-Content -Path $StartLayout -Encoding UTF8 -Forceforeach ($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:APPDATA\Microsoft\Windows\Start menu\Programs\System Tools\$DevicesPrinters.lnk")$Shortcut.TargetPath = "control"$Shortcut.Arguments = "printers"$Shortcut.IconLocation = "$env:SystemRoot\system32\DeviceCenter.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 Startif ($Group){$DesktopApplicationID = ($Parameters | Where-Object -FilterScript {$_.Name -eq $Tile}).AppIDif (-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 columnif ($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 layoutif (-not (Test-Path -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer)){New-Item -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Force}New-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name LockedStartLayout -Value 1 -ForceNew-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name StartLayoutFile -Value $StartLayout -ForceStart-Sleep -Seconds 3# Restart the Start menuStop-Process -Name StartMenuExperienceHost -Force -ErrorAction IgnoreStart-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 layoutRemove-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name LockedStartLayout -Force -ErrorAction IgnoreRemove-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name StartLayoutFile -Force -ErrorAction IgnoreRemove-Item -Path $StartLayout -ForceStop-Process -Name StartMenuExperienceHost -Force -ErrorAction IgnoreStart-Sleep -Seconds 3# Open the Start menu to load the new layout$wshell = New-Object -ComObject WScript.Shell$wshell.SendKeys("^{ESC}")}

Страница GitHub Windows 10 Sophia Script, где в том числе используется данный метод.

Огромное спасибо iNNOKENTIY21 за помощь в реализации метода.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru