И случайно, самое полное описание WshShortcut
.
Почему-то, уж не знаю почему, в .NET Framework (во всяком случае до 4 версии, в 4 вроде появился) не было стандартного способа создать ярлык (файл .LNK) программно. Но способы все-таки есть. Расскажу о них, в порядке уменьшения геморройности.
Самый геморройный способ, для любителей ассемблера и прочего байтокопательства. Файл ярлыка (*.lnk
), это обычный бинарный файл. Почему-то в сети бытует мнение, что формат LNK-файлов закрыт, и чуть ли не засекречен. Однако это не так, спецификация формата вполне себе открыта и лежит на официальном сайте Microsoft. Так что остается осилить 48 страничную спецификацию, и можно приступать. 🙂 Но мы этого делать не будем. Замечу лишь, что в формате файла есть несколько странных моментов. Например, зачем хранить в файле ярлыка серийный номер тома и тип диска (HDD, CD, Floppy) и NetBIOS имя компьютера, я совершенно не понимаю.
Способ, наиболее часто встречающийся в сети, но почему-то, весьма поверхностно описанный. Windows Script Host — компонент Microsoft Windows, предназначенный для запуска сценариев на скриптовых языках JScript и VBScript, а также и на других дополнительно устанавливаемых языках (например, Perl).
Остановлюсь поподробнее на некоторых моментах. Сначала самое основное.
В References проекта надо добавить соответствующий компонент (щелкнуть по References правой кнопкой мыши, выбрать Add Reference…) В появившемся окне выбираем вкладку COM и находим компонент Windows Script Host Object Model.
Из-за того, что мы используем COM-интерфейс, с нашей программой придется таскать библиотеку для взаимодействия с ним Interop.IWshRuntimeLibrary.dll
(ее нам без нашего участия сделает компилятор .NET).
Теперь указываем соответствующую директиву using
:
using IWshRuntimeLibrary;
Создаем объект WSH Shell:
WshShell wshShell = new WshShell(); //создаем объект wsh shell
На самом деле у объекта WshShell
довольно много интересных возможностей, например выполнять VBS или JS сценарии прямо из кода C#, со всеми возможностями Windows Scripting Host, естественно. Но это так, к слову. Мы же создадим объект для управления ярлыком:
IWshShortcut Shortcut = (IWshShortcut)wshShell.
CreateShortcut(ShortcutPath);
где ShortcutPath
— строковая переменная, в которую записан путь к файлу создаваемого ярлыка.
В самом простейшем случае, надо задать имя файла для которого создается ярлык:
Shortcut.TargetPath = @"C:\Windows\notepad.exe"; //путь к целевому файлу
Если дополнительные параметры не заданы, то:
— в качестве иконки ярлыка будет установлена иконка по умолчанию (для EXE — его иконка, для остальных — стандартные системные иконки)
— в качестве рабочего каталога — каталог, в котором расположен целевой файл (тут C:\Windows\
).
— размер окна — нормальный.
Теперь нужно сохранить ярлык:
Shortcut.Save();
Пример кода целиком на PasteBin
Теперь о дополнительных параметрах, которым особо никто внимания не уделяет, а там скрыто несколько мелких гадостей и глюков.
Пример кода функции, задающей дополнительные параметры ярлыка на PasteBin
Рабочий каталог:
Задается строковым параметром Shortcut.WorkingDirectory
. Если его не задавать вообще, то, как я ранее говорил, WshShell
пропишет в ярлык каталог, в котором расположен целевой файл. А вот если задать, то он пропишет туда любую строку без всякой проверки. Если строка будет null
или пустой, то и каталог будет не указан. Если, например, нужно в случае указания null
прописывать каталог целевого файла, то можно сделать это таким образом:
void Create(string ShortcutPath, string TargetPath, string WorkingDirectory) { //... //в качестве рабочей директории установим каталог с файлом //для которого cоздаем ярлык если рабочий каталог null if (WorkingDirectory == null) { Shortcut.WorkingDirectory = System.IO.Path.GetDirectoryName(TargetPath); } else { Shortcut.WorkingDirectory = WorkingDirectory; } //... }
Стиль окна приложения:
Задается параметром int Shortcut.WindowStyle
Значения параметра следующие:
1 — обычный размер окна (Normal
)
3 — развернутое на весь экран (Maximize
)
7 — свернутое в трей (Minimize
)
Попытка задать другое значение, приводит к установке параметра в 1.
Для удобства можно создать перечисление:
public enum ShortcutWindowStyle { Normal = 1, Maximize = 3, Minimize = 7 }
и задавать параметр таким образом:
Shortcut.WindowStyle = (int)WindowStyle;
Параметры командной строки:
задаются параметром string Shortcut.Arguments
Иконка ярлыка:
Задается параметром string Shortcut.IconLocation
Строка IconLocation
имеет следующий формат имя_файла, [индекс_иконки]
где имя_файла
— имя exe, dll или ico файла, содержащего иконку.
индекс_иконки
— индекс иконки в файле exe или dll, для ico файлов является необязательным.
Если параметр не задать, то ярлыку будет установлена иконка по умолчанию, «родная» иконка для исполняемого файла, и соответствующая типу файла, для других файлов.
Внимание! Если значение этой строки будет пустым или null
, то это приведет к ошибке ArgumentException "Значение не попадает в ожидаемый диапазон."
, так что необходима соответствующая проверка.
//Иконка if (!string.IsNullOrEmpty(Icon)) { Shortcut.IconLocation = Icon; }
Описание ярлыка:
Задается параметром string Shortcut.Description
, отображается как всплывающая подсказка при наведении курсора на ярлык.
Горячая клавиша:
Задается параметром string Shortcut.Hotkey
Внимание! Если переменной попытаться установить значение null
, произойдет ошибка нехватки памяти (OutOfMemoryException
). Любая строка не подпадающая под формат, вызывает ArgumentException "Значение не попадает в ожидаемый диапазон."
Строка должна быть следующего вида: "Ctrl+Alt+N"
, т.е. содержать названия клавиш-модификаторов, символьную или функциональную клавишу, названия должны быть разделены знаком + без пробелов. Названия регистронезависимы.
Чтобы хоткей сработал, ярлык надо создавать или в меню Пуск, или на Рабочем столе. Почему-то если создать ярлык где-то еще, а потом скопировать в Пуск или на Рабочий стол, хоткей не работает (хотя, если менять горячую клавишу у уже созданного ярлыка, через свойства ярлыка, то все работает). Установленный хоткей становится глобальным для всей системы, т.е. если "Ctrl+Alt+N"
обрабатывается в какой-то программе, то после создания ярлыка, сочетание клавиш будет перехвачено Windows, и запустится то, на что указывает ярлык.
Список возможных клавиш:
Модификаторы: CTRL+ ALT+ SHIFT+
(и еще какой-то EXT+
встречается в [1])
Алфавитно-цифровые, функциональные и прочие:
F1-F12, 0-9, A-Z
(указывается как
ESC, ENTER, TAB, SPACE, PRINT SCREEN SNAPSHOT
), BACKSPACE
[1] (причем обычным способом через проводник установить их нельзя, и нет, Ctrl+Alt+Del так не перехватить, хотя создать такой хоткей можно).
Полный список клавиш можно посмотреть в WINUSER.H
или в [2], имена берутся без VK_
, и не получится в качестве третьей клавиши использовать имена модификаторов и мышиных кнопок, ярлык создастся без ошибок, а вот работать не будет.
Через свойства ярлыка нельзя задать горячую клавишу БЕЗ модификаторов. Windows заботливо будет нам подставлять CTRL+ALT+
, а вот с помощью WshShortcut
— можно, т.е. если значение Hotkey
установить, например в «F1"
и создать ярлык на Рабочем столе, то по нажатию F1 будет вызываться, например, Блокнот. На практике это использовать, конечно, никак нельзя, разве что над кем-нибудь подшутить.
Демо и класс-обертка над IWshShortcut
на GitHub
Вообще, этот способ по геморройности надо было бы ставить на второе место, чего одна статья [3], описывающая все API, стоит. Но авторы статьи, крутые акулы программирования, для нас постарались и таки сделали классы для работы с ярлыками, причем сделали великолепно! С помощью их класса ShellLink
можно не только создавать новые ярлыки, но и читать/редактировать существующие.
ShellLink вместе с демо можно скачать с mega.nz или с моего репозитория на GitHub, не знаю, будут ли проблемы с лицензией, но на vbaccelerator.com вроде Creative Commons.
С официального сайта почему-то сей полезный горшочек пропал, хотя статья осталась. Видать авторы забили на проект и что-то протухло.
Повторюсь, класс написан хорошо, ничего не падает и с ошибками не вылетает. Единственное, что криво, это установка хоткея. Ну да и черт с ним, мне особо не нужно было, так что ковыряться и исправлять не стал.
Написано сие дело аж в 2003 г., но прекрасно работает до сих пор, на Windows 7 в т.ч.
Для подключения к своему проекту из оригинального архива понадобятся два класса (файлы ShellLink.cs
и FileIcon.cs
), далее подключаем соответствующий namespace (using vbAccelerator.Components.Shell;
) и можно использовать. Пример кода:
ShellLink shortcut = new ShellLink();
shortcut.ShortCutFile = @"C:\Temp\shortcut\test.lnk";
shortcut.Target = @"C:\Windows\notepad.exe";
shortcut.WorkingDirectory = @"C:\";
shortcut.IconPath = @"C:\Windows\System32\shell32.dll";
shortcut.IconIndex=111;
shortcut.Description = "Тестовый ярлык";
shortcut.Arguments = "file.txt";
shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmMaximized;
shortcut.Save();
1. WshShortcut.Hotkey Копия
2. Virtual-Key Codes Копия
3. Creating and Modifying Shortcuts (ShellLink, WebArchive) Копия
4. Создание ярлыков с помощью Windows Script Host
5. Спецификация формата файлов LNK Копия
1. ShellLink
от vbaccelerator. Скачать с Mega.NZ. На GitHub
2. Демо и класс-обертка над IWshShortcut
на GitHub
Pingback: Шпионский ярлык, небольшая заметка с экспериментом. | Персональный блог Толика Панкова