Ссылки оболочки
Ссылка оболочки — это объект данных, содержащий сведения, используемые для доступа к другому объекту в пространстве имен Оболочки, то есть любой объект, видимый через проводник Windows. Типы объектов, к которым можно получить доступ через ссылки оболочки, включают файлы, папки, диски и принтеры. Ссылка оболочки позволяет пользователю или приложению получать доступ к объекту из любого места в пространстве имен. Пользователю или приложению не нужно знать текущее имя и расположение объекта.
-
ссылки оболочки
- разрешения ссылок
- ссылки на файлы
- идентификаторы элементов и списки идентификаторов
- использование ссылок оболочки
Сведения о ссылках оболочки
Пользователь создает ссылку оболочки, выбрав команду Создать ярлык в контекстном меню объекта. Система автоматически создает значок для ссылки оболочки, сочетая значок объекта с небольшой стрелкой (известной как системный значок наложения ссылки), который отображается в левом нижнем углу значка. Ссылка оболочки с значком называется ярлыком; однако ссылки оболочки и ярлык часто используются взаимозаменяемо. Как правило, пользователь создает ярлыки для быстрого доступа к объектам, хранящимся в вложенных папках или в общих папках на других компьютерах. Например, пользователь может создать ярлык для документа Microsoft Word, расположенного в подпапке, и поместить значок ярлыка на рабочий стол. Затем пользователь может открыть документ, дважды щелкнув значок ярлыка. Если документ перемещен или переименован после создания ярлыка, система попытается обновить ярлык при следующем выборе пользователя.
Приложения также могут создавать и использовать ссылки оболочки и сочетания клавиш. Например, приложение обработки слов может создать ссылку оболочки для реализации списка последних использованных документов. Приложение создает ссылку оболочки с помощью интерфейса IShellLink для создания объекта ссылки Оболочки. Приложение использует интерфейс IPersistFile или IPersistStream для хранения объекта в файле или потоке.
Заметка
Для создания ссылки на URL-адрес нельзя использовать IShellLink.
В этом обзоре описывается интерфейс IShellLink и объясняется, как использовать его для создания и разрешения ссылок оболочки из приложения на основе Microsoft Win32. Так как проектирование ссылок оболочки основано на объектной модели КОМПОНЕНТОВ OLE (COM), перед чтением этого обзора необходимо ознакомиться с основными понятиями программирования COM и OLE.
Разрешение ссылок
Если пользователь создает ярлык для объекта, а имя или расположение объекта изменено позже, система автоматически выполняет шаги по обновлению или разрешению, ярлык при следующем выборе пользователя. Однако если приложение создает ссылку оболочки и сохраняет ее в потоке, система не пытается разрешить эту ссылку автоматически. Приложение должно разрешить ссылку, вызвав метод IShellLink::Resolve.
При создании ссылки оболочки система сохраняет сведения о ссылке. При разрешении ссылки (автоматически или с помощью вызова IShellLink::Resolve) система сначала извлекает путь, связанный со ссылкой оболочки, с помощью указателя на список идентификаторов ссылки оболочки. Дополнительные сведения о списке идентификаторов см. в разделе Идентификаторы элементов и списки идентификаторов. Система ищет связанный объект в этом пути и, если он находит объект, разрешает ссылку. Если система не может найти объект, он вызывает службу отслеживания распределенных ссылок и идентификаторов объектов (DLT), если она доступна, чтобы найти объект. Если служба DLT недоступна или не может найти объект, система выглядит в том же каталоге для объекта с тем же временем создания и атрибутами файла, но с другим именем. Этот тип поиска разрешает ссылку на объект, который был переименован.
Если система по-прежнему не может найти объект, он выполняет поиск каталогов, рабочих столов и локальных томов, глядя рекурсивно, хотя дерево каталогов для объекта с тем же именем или временем создания. Если система по-прежнему не находит совпадения, отображается диалоговое окно с запросом пользователя на расположение. Приложение может отключить диалоговое окно, указав значение SLR_NO_UI в вызове IShellLink::Resolve.
Инициализация библиотеки объектов компонента
Перед созданием и разрешением ярлыков приложение должно инициализировать библиотеку объектов компонента, вызвав функцию CoInitialize. Для каждого вызова CoInitialize требуется соответствующий вызов функции CoUninitialize, которую приложение должно вызывать при завершении работы. Вызов CoUninitialize гарантирует, что приложение не завершает работу до получения всех ожидающих сообщений.
имена Location-Independent
Система предоставляет независимые от расположения имена для ссылок оболочки на объекты, хранящиеся в общих папках. Если объект хранится локально, система предоставляет локальный путь и имя файла для объекта. Если объект хранится удаленно, система предоставляет имя сетевого ресурса универсального соглашения об именовании (UNC) для объекта. Так как система предоставляет независимые от расположения имена, ссылка оболочки может служить универсальным именем для файла, который можно передать на другие компьютеры.
Ссылки на файлы
Когда пользователь создает ярлык для объекта, выбрав команду Создать ярлык в контекстном меню объекта, Windows сохраняет сведения, необходимые для доступа к объекту в файле ссылки— двоичном файле с расширением имени файла .lnk. Файл ссылки содержит следующие сведения:
- Расположение (путь) объекта, на который ссылается ярлык (называемый соответствующим объектом).
- Рабочий каталог соответствующего объекта.
- Список аргументов, которые система передает соответствующему объекту при активации метода IContextMenu::InvokeCommand для ярлыка.
- Команда show, используемая для задания начального состояния отображения соответствующего объекта. Это одно из значений SW_, описанных в ShowWindow.
- Расположение (путь и индекс) значка ярлыка.
- Строка описания ярлыка.
- Сочетание клавиш для сочетания клавиш.
При удалении файла ссылки соответствующий объект не затрагивается.
Если вы создаете ярлык для другого ярлыка, система просто копирует файл ссылки, а не создает новый файл ссылки. В этом случае сочетания клавиш не будут независимыми друг от друга.
Приложение может зарегистрировать расширение имени файла в качестве ярлыка типа файла. Если файл имеет расширение имени файла, зарегистрированное в качестве типа ярлыка, система автоматически добавляет в значок файла значок наложения наложение (небольшая стрелка). Чтобы зарегистрировать расширение имени файла в качестве ярлыка типа файла, необходимо добавить значение IsShortcut в описание расширения имени файла, как показано в примере ниже. Обратите внимание, что оболочка должна быть перезапущена, чтобы значок наложения вступил в силу. IsShortcut не имеет значения данных.
HKEY_CLASSES_ROOT
.xyz
(Default) = XYZApp
XYZApp
IsShortcut
Сочетания клавиш
Имя ярлыка, представляющее собой строку, которая отображается под значком ссылки оболочки, фактически является именем самого ярлыка. Пользователь может изменить строку описания, выбрав ее и введя новую строку.
Расположение сочетаний клавиш в пространстве имен
Ярлык может существовать на рабочем столе или в любом месте пространства имен Оболочки. Аналогичным образом объект, связанный с ярлыком, также может существовать в любом месте пространства имен Оболочки. Приложение может использовать метод IShellLink::SetPath, чтобы задать путь и имя файла для связанного объекта, а метод IShellLink::GetPath для получения текущего пути и имени файла для объекта.
Ярлык рабочего каталога
Рабочий каталог — это каталог, в котором соответствующий объект ярлыка загружает или сохраняет файлы, когда пользователь не определяет определенный каталог. Файл ссылки содержит имя рабочего каталога для соответствующего объекта. Приложение может задать имя рабочего каталога для соответствующего объекта с помощью метода IShellLink::SetWorkingDirectory и получить имя текущего рабочего каталога соответствующего объекта с помощью метода IShellLink::GetWorkingDirectory.
Сочетания аргументов командной строки
Файл ссылки содержит аргументы командной строки, которые оболочка передает соответствующему объекту, когда пользователь выбирает ссылку. Приложение может задать аргументы командной строки для ярлыка с помощью метода IShellLink::SetArguments. Полезно задать аргументы командной строки, если соответствующее приложение, например компоновщик или компилятор, принимает специальные флаги в качестве аргументов. Приложение может получить аргументы командной строки из ярлыка с помощью метода IShellLink::GetArguments.
Сочетания клавиш для отображения команд
Когда пользователь дважды щелкает ярлык, система запускает приложение, связанное с соответствующим объектом, и задает начальное состояние приложения на основе команды show, указанной ярлыком. Команда show может быть любой из SW_ значений, включенных в описание функции ShowWindow. Приложение может задать команду show для ярлыка с помощью метода IShellLink::SetShowCmd и получить текущую команду show с помощью метода IShellLink::GetShowCmd.
Ярлыки
Как и другие объекты Оболочки, ярлык имеет значок. Пользователь обращается к объекту, связанному с ярлыком, дважды щелкнув значок ярлыка. Когда система создает значок ярлыка, он использует растровое изображение соответствующего объекта и добавляет системный значок наложения ссылки (небольшая стрелка) в левый нижний угол. Приложение может задать расположение (путь и индекс) значка ярлыка с помощью метода IShellLink::SetIconLocation. Приложение может получить это расположение с помощью метода IShellLink::GetIconLocation.
Описания ярлыков
Ярлыки имеют описания, но пользователь никогда не видит их. Приложение может использовать описание для хранения любой текстовой информации. Описания задаются с помощью метода IShellLink::SetDescription и извлекаются с помощью метода IShellLink::GetDescription.
Сочетания клавиш
С ним может быть связана сочетания клавиш. Сочетания клавиш позволяют пользователю нажимать сочетание клавиш для активации сочетания клавиш. Приложение может задать сочетание клавиш для сочетания клавиш с помощью метода IShellLink::SetHotkey и получить текущее сочетание клавиш с помощью метода IShellLink::GetHotkey.
Идентификаторы элементов и списки идентификаторов
Оболочка использует идентификаторы объектов в пространстве имен Оболочки. Все объекты, видимые в оболочке (файлы, каталоги, серверы, рабочие группы и т. д.), имеют уникальные идентификаторы среди объектов в родительской папке. Эти идентификаторы называются идентификаторами элементов, и они имеют тип данных SHITEMID, как определено в файле заголовка Shtypes.h. Идентификатор элемента — это поток байтов переменной длины, содержащий сведения, определяющие объект в папке. Только создатель идентификатора элемента знает содержимое и формат идентификатора. Единственной частью идентификатора элемента, который использует оболочка, является первые два байта, которые указывают размер идентификатора.
Каждая родительская папка имеет собственный идентификатор элемента, который идентифицирует его в своей родительской папке. Таким образом, любой объект Shell можно однозначно определить по списку идентификаторов элементов. Родительская папка сохраняет список идентификаторов для элементов, содержащихся в ней. Список содержит тип данных ITEMIDLIST. Списки идентификаторов элементов выделяются оболочкой и могут передаваться через интерфейсы оболочки, например IShellFolder. Важно помнить, что каждый идентификатор в списке идентификаторов элементов имеет смысл только в контексте родительской папки.
Приложение может задать список идентификаторов элементов ярлыка с помощью метода IShellLink::SetIDList. Этот метод полезен при настройке ярлыка для объекта, который не является файлом, например принтером или диском. Приложение может получить список идентификаторов элементов ярлыка с помощью метода IShellLink::GetIDList.
Использование ссылок оболочки
В этом разделе содержатся примеры, демонстрирующие создание и разрешение ярлыков из приложения на основе Win32. В этом разделе предполагается, что вы знакомы с программированием Win32, C++и OLE COM.
Создание ярлыка и ярлыка папки в файле
Пример функции CreateLink в следующем примере создает ярлык. Параметры включают указатель на имя файла для ссылки, указатель на имя создаваемого ярлыка, а также указатель на описание ссылки. Описание состоит из строки "Ярлык для имени файла", где имя файла — это имя файла для ссылки.
Чтобы создать ярлык папки с помощью примера функции CreateLink, вызовите CoCreateInstance с помощью CLSID_FolderShortcut вместо CLSID_ShellLink (CLSID_FolderShortcut поддерживает IShellLink). Все остальные коды остаются неизменными.
Так как CreateLink вызывает функциюCoCreateInstance, предполагается, что функция CoInitialize уже вызвана. CreateLink использует интерфейс IPersistFile для сохранения ярлыка и интерфейса IShellLink для хранения имени файла и описания.
// CreateLink - Uses the Shell's IShellLink and IPersistFile interfaces
// to create and store a shortcut to the specified object.
//
// Returns the result of calling the member functions of the interfaces.
//
// Parameters:
// lpszPathObj - Address of a buffer that contains the path of the object,
// including the file name.
// lpszPathLink - Address of a buffer that contains the path where the
// Shell link is to be stored, including the file name.
// lpszDesc - Address of a buffer that contains a description of the
// Shell link, stored in the Comment field of the link
// properties.
#include "stdafx.h"
#include "windows.h"
#include "winnls.h"
#include "shobjidl.h"
#include "objbase.h"
#include "objidl.h"
#include "shlguid.h"
HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc)
{
HRESULT hres;
IShellLink* psl;
// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
// has already been called.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
// Set the path to the shortcut target and add the description.
psl->SetPath(lpszPathObj);
psl->SetDescription(lpszDesc);
// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
// Add code here to check return value from MultiByteWideChar
// for success.
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
return hres;
Разрешение ярлыка
Приложению может потребоваться доступ к ярлыку, созданному ранее, и управлять ими. Эта операция называется разрешением ярлыка.
Определяемая приложением функция ResolveIt в следующем примере разрешает ярлык. Его параметры включают дескриптор окна, указатель на путь ярлыка и адрес буфера, получающего новый путь к объекту. Дескриптор окна определяет родительское окно для всех полей сообщений, которые может потребоваться отобразить оболочке. Например, оболочка может отобразить окно сообщения, если ссылка находится на не общих носителях, если возникают проблемы с сетью, если пользователь должен вставить диск с флоппи-диском и т. д.
Функция ResolveIt вызывает функцию CoCreateInstance и предполагает, что функция CoInitialize уже вызвана. Обратите внимание, что ResolveIt должен использовать интерфейс IPersistFile для хранения сведений о ссылке. IPersistFile реализуется объектом IShellLink. Перед получением сведений о пути необходимо загрузить сведения о ссылке, которая показана далее в примере. Сбой загрузки сведений о ссылке приводит к сбою вызовов IShellLink::GetPath и IShellLink::GetDescription функции-члены.
// ResolveIt - Uses the Shell's IShellLink and IPersistFile interfaces
// to retrieve the path and description from an existing shortcut.
//
// Returns the result of calling the member functions of the interfaces.
//
// Parameters:
// hwnd - A handle to the parent window. The Shell uses this window to
// display a dialog box if it needs to prompt the user for more
// information while resolving the link.
// lpszLinkFile - Address of a buffer that contains the path of the link,
// including the file name.
// lpszPath - Address of a buffer that receives the path of the link
target, including the file name.
// lpszDesc - Address of a buffer that receives the description of the
// Shell link, stored in the Comment field of the link
// properties.
#include "stdafx.h"
#include "windows.h"
#include "shobjidl.h"
#include "shlguid.h"
#include "strsafe.h"
HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPWSTR lpszPath, int iPathBufferSize)
{
HRESULT hres;
IShellLink* psl;
WCHAR szGotPath[MAX_PATH];
WCHAR szDescription[MAX_PATH];
WIN32_FIND_DATA wfd;
*lpszPath = 0; // Assume failure
// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
// has already been called.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
// Get a pointer to the IPersistFile interface.
hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz, MAX_PATH);
// Add code here to check return value from MultiByteWideChar
// for success.
// Load the shortcut.
hres = ppf->Load(wsz, STGM_READ);
if (SUCCEEDED(hres))
{
// Resolve the link.
hres = psl->Resolve(hwnd, 0);
if (SUCCEEDED(hres))
{
// Get the path to the link target.
hres = psl->GetPath(szGotPath, MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH);
if (SUCCEEDED(hres))
{
// Get the description of the target.
hres = psl->GetDescription(szDescription, MAX_PATH);
if (SUCCEEDED(hres))
{
hres = StringCbCopy(lpszPath, iPathBufferSize, szGotPath);
if (SUCCEEDED(hres))
{
// Handle success
}
else
{
// Handle the error
}
}
}
}
}
// Release the pointer to the IPersistFile interface.
ppf->Release();
}
// Release the pointer to the IShellLink interface.
psl->Release();
}
return hres;
}
Создание ярлыка для объекта Nonfile
Создание ярлыка для объекта, не являющегося файлом, например принтера, аналогично созданию ярлыка для файла, за исключением того, что вместо установки пути к файлу необходимо задать список идентификаторов принтеру. Чтобы задать список идентификаторов, вызовите метод IShellLink::SetIDList, указав адрес списка идентификаторов.
Каждый объект в пространстве имен Оболочки имеет идентификатор элемента. Оболочка часто объединяет идентификаторы элементов в списки, завершаемые null, состоящие из любого количества идентификаторов элементов. Дополнительные сведения об идентификаторах элементов см. в разделе Идентификаторы элементов и списки идентификаторов.
Как правило, если необходимо задать ярлык для элемента, не имеющего имени файла, например принтера, у вас уже будет указатель на интерфейс объекта IShellFolder. IShellFolder используется для создания расширений пространства имен.
Получив идентификатор класса для IShellFolder, можно вызвать функцию CoCreateInstance, чтобы получить адрес интерфейса. Затем можно вызвать интерфейс, чтобы перечислить объекты в папке и получить адрес идентификатора элемента для объекта, который вы ищете. Наконец, можно использовать адрес в вызове функции-члена IShellLink::SetIDList для создания ярлыка для объекта.