Работа с ярлыками через PowerShell

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
7,814
Реакции
6,593
Автор: Алексей Пахунов.
Оригинальное название статьи: .NET обертка для IShellLink.
Источник.


Наконец-то дописал .NET обертку для IShellLink (см. серию постов начиная с Shortcuts, shell and COM apartments.). Теперь можно создавать и редактировать ярлыки прямо из PowerShell.
icon_smile.gif


Вот ссылка на исходный код проекта. Немного позже, если дойдут руки, выложу ссылку на готовую инсталляцию.

Вся полезная функциональность реализуется одним классом – ShellLink, который объединяет в себе три интерфейса: IShellLink, IShellLinkDataList и IPersistFile. Большая часть методов этих интерфейсов была переделана в .NET свойства для удобства использования.

PowerShell и CLSID_ShellLink используют разные модели COM apartments: PowerShell использует MTA, а CLSID_ShellLink, как и большинство объектов Shell, – STA. В результате, не получается вызывать методы интерфейса IShellLinkDataList, который не поддерживает маршалинг через границу apartments. Для решения этой проблемы используется ShellPS.dll, которая представляет собой не что иное, как proxy/stub DLL для интерфейса IShellLinkDataList (см. COM marshalling: создание proxy/stub на коленке.).

В собранном виде весь проект состоит из двух библиотек: ShellLib.dll, которая содержит реализацию класса ShellLink и всех вспомогательных классов, и ShellPS.dll. Обе библиотеки собираются с помощью WDK, причём для сборки ShellLib.dll требуется .NET библиотеки из поставки Visual Studio .NET 2005. Эта комбинация потребовала использования нетривиальных возможностей SOURCES в виде директивы LINKER_OPTIDATA.

Перед использованием, скомпилированные DLL нужно зарегистрировать:
Код:
regsvr32 ShellPS.dll
gacutil /i ShellLib.dll

После чего можно запустить PowerShell и исследовать новые возможности.
PowerShell:
# Загружаем ShellLib.dll
[System.Reflection.Assembly]::Load(
    "shelllib, Version=1.0.1.1, Culture=neutral,
    PublicKeyToken=e0a879bef00d4c8e,
    processorArchitecture=x86")
| out-null

# Открываем ярлык "Command Prompt.lnk"
$filename = $env:USERPROFILE +
    "\\Start Menu\\Programs\\Accessories\\Command Prompt.lnk"

$link = new-object ShellLib.ShellLink
$link.Load(
    $filename,
    [ShellLib.EPersistFileModeFlags]::STGM_READWRITE)

$link

Последняя команда выведет текущие значения основных свойств ярлыка:



Покажем список всех доступных методов и свойств:
PowerShell:
$link | get-member


Свойство ConsoleProps соответствует вкладкам “Options”, “Font”, “Layout” и “Colors” в стандартном окне свойств ярлыка. В данный момент свойство ConsoleProps не задано, что соответствует всем значениям по умолчанию:



Попробуем задать свой размер окна и шрифт:
PowerShell:
$props = new-object ShellLib.NtConsoleProps
$props.wFillAttribute = 7
$props.wPopupFillAttribute = 245
$props.dwScreenBufferSize = new-object System.Drawing.Point(180, 3000)
$props.dwWindowSize = new-object System.Drawing.Point(180, 79)
$props.dwFontSize = new-object System.Drawing.Point(7, 12)
$props.uFontFamily = 54
$props.uFontWeight = 400
$props.FaceName = “Lucida Console”
$props.uCursorSize = 15
$props.bQuickEdit = 1
$props.bInsertMode = 1
$props.uHistoryBufferSize = 50
$props.uNumberOfHistoryBuffers = 4
$link.ConsoleProps = $props

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

Теперь можно сохранить полученные изменения.
PowerShell:
$link.Save($filename, 1)

В результате всех этих действий вот такой результат:




Осталось только оформить это всё в один скрипт и готово!
icon_smile.gif
 
Последнее редактирование:
Назад
Сверху Снизу