Аннотация:
В статье рассматривается предоставляемый Windows механизм программного доступа к ярлыкам (shortcuts) — реализуемые COM-классом ShellLink интерфейсы IShellLink и IPersistFile, методы которых позволяют читать и изменять свойства уже существующих ярлыков, а также создавать новые ярлыки.
Здравствуйте, Илья Зарецкий, Вы писали:
ИЗ>Аннотация: ИЗ>В статье рассматривается предоставляемый Windows механизм программного доступа к ярлыкам (shortcuts) — реализуемые COM-классом ShellLink интерфейсы IShellLink и IPersistFile, методы которых позволяют читать и изменять свойства уже существующих ярлыков, а также создавать новые ярлыки.
Обычно программисты вместо изучения теории предпочитают просто взять готовый для употребления класс. Который и предлагается вашему вниманию.
Shortcut.h:
#if !defined(AFX_SHORTCUT_H__75CC4921_7AF9_4A38_A5FD_D815FA498111__INCLUDED_)
#define AFX_SHORTCUT_H__75CC4921_7AF9_4A38_A5FD_D815FA498111__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif// _MSC_VER > 1000class CShortcut
{
public:
CShortcut();
virtual ~CShortcut();
// Resolves shortcut specified by ANSI path
BOOL ResolveShortcut(LPCSTR pFileName);
// Resolves shortcut specified by Unicode path
BOOL ResolveShortcut(LPCWSTR pUnicodeFileName);
// Returns path of a target file
CString GetFilePath();
// Returns name of a target file
CString GetFileName();
// Returns last modification time of a target file
FILETIME GetFileTime();
// Determines if target file is directory
BOOL IsDirectory();
// Returns PIDL for a target file
LPITEMIDLIST GetIDList();
// Creates link for specified file
BOOL CreateLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc = NULL);
protected:
IShellLink* m_pShellLink;
IPersistFile* m_pPersistFile;
char FilePath[MAX_PATH];
WIN32_FIND_DATA FindData;
};
#endif// !defined(AFX_SHORTCUT_H__75CC4921_7AF9_4A38_A5FD_D815FA498111__INCLUDED_)
Shortcut.cpp:
#include"stdafx.h"#include <shlwapi.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CShortcut::CShortcut()
{
m_pShellLink = NULL;
m_pPersistFile = NULL;
// Query IShellLink and IPersistFile interfaces
HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void**)&m_pShellLink);
if (SUCCEEDED(hr))
hr = m_pShellLink->QueryInterface(IID_IPersistFile, (void**)&m_pPersistFile);
}
CShortcut::~CShortcut()
{
// Release interfacesif(m_pPersistFile)
m_pPersistFile->Release();
if(m_pShellLink)
m_pShellLink->Release();
}
// Resolves shortcut specified by ANSI path
BOOL CShortcut::ResolveShortcut(LPCSTR pFileName)
{
// Loading the shortcut
WCHAR UnicodeFileName[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, pFileName, -1, UnicodeFileName, MAX_PATH);
return ResolveShortcut(UnicodeFileName);
}
// Resolves shortcut specified by Unicode path
BOOL CShortcut::ResolveShortcut(LPCWSTR pUnicodeFileName)
{
if (!m_pPersistFile)
return FALSE;
HRESULT hr = m_pPersistFile->Load(pUnicodeFileName, STGM_READ);
if (FAILED(hr)) return FALSE;
// Resolving the shortcut
// 0x10 - SLR_NOSEARCH
// 0x20 - SLR_NOTRACK
// 0x40 - SLR_NOLINKINFO
hr = m_pShellLink->Resolve(NULL, SLR_ANY_MATCH | SLR_NO_UI | SLR_NOUPDATE | 0x10 | 0x20 | 0x40);
if (FAILED(hr)) return FALSE;
// Fetching resolving results
ZeroMemory(&FilePath, MAX_PATH);
ZeroMemory(&FindData, sizeof(FindData));
hr = m_pShellLink->GetPath(FilePath, MAX_PATH, &FindData, SLGP_RAWPATH);
return SUCCEEDED(hr);
}
// Returns path of a target file
CString CShortcut::GetFilePath()
{
return FilePath;
}
// Returns name of a target file
CString CShortcut::GetFileName()
{
return FindData.cFileName;
}
// Returns last modification time of a target file
FILETIME CShortcut::GetFileTime()
{
return FindData.ftLastWriteTime;
}
// Determines if target file is directory
BOOL CShortcut::IsDirectory()
{
return (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}
// Returns PIDL for a target file
LPITEMIDLIST CShortcut::GetIDList()
{
LPITEMIDLIST pidl;
m_pShellLink->GetIDList(&pidl);
return pidl;
}
// Creates link for specified file
BOOL CShortcut::CreateLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc)
{
// Change extension of link file to "lnk"char Link[MAX_PATH];
lstrcpy(Link, lpszPathLink);
PathRenameExtension(Link, ".lnk");
// Set path to the shortcut target and add description
HRESULT hr = m_pShellLink->SetPath(lpszPathObj);
hr = m_pShellLink->SetDescription(lpszDesc);
if (m_pPersistFile)
{
WCHAR wsz[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, Link, -1, wsz, MAX_PATH);
// Save the link
hr = m_pPersistFile->Save(wsz, TRUE);
}
return SUCCEEDED(hr);
}
Здравствуйте, algol, Вы писали:
A>Обычно программисты вместо изучения теории предпочитают просто взять готовый для употребления класс.
Гх-м-м... дабы не ставить под сомнение ни чью профессиональную квалификацию, не буду приводить примеры постов, причиной появления которых является именно подобный подход. А вообще, это вечный спор из серии "нужно ли знать устройство автомобиля, чтобы его водить" — тема ИМХО очень флеймовая.
A>Который и предлагается вашему вниманию.
Здравствуйте, Илья Зарецкий, Вы писали:
ИЗ>Статья:
ИЗ>Авторы: ИЗ> Илья Зарецкий
ИЗ>Аннотация: ИЗ>В статье рассматривается предоставляемый Windows механизм программного доступа к ярлыкам (shortcuts) — реализуемые COM-классом ShellLink
shortcuts — это, конечно, хорошо... Но вот кто знает, как программно можно создать такой "анахронизм", как pif-файл к старому досовскому приложению (разумеется, задав специфические настройки этого pif-файла) ?
Я однажды перерых MSDN и так ничего вразумительного не обнаружил
Здравствуйте, siv, Вы писали:
siv>shortcuts — это, конечно, хорошо... Но вот кто знает, как программно можно создать такой "анахронизм", как pif-файл к старому досовскому приложению (разумеется, задав специфические настройки этого pif-файла) ?
А что будет, если программно создать шорткат на ДОСовую прогу?
Здравствуйте, siv, Вы писали:
siv>shortcuts — это, конечно, хорошо... Но вот кто знает, как программно можно создать такой "анахронизм", как pif-файл к старому досовскому приложению (разумеется, задав специфические настройки этого pif-файла) ? siv>Я однажды перерых MSDN и так ничего вразумительного не обнаружил
Наверное pif файл создается также, как и lnk. По крайней мере в описании функции SHGetNewLinkInfo написано: "SHGetNewLinkInfo will determine the executable type of the target. If pszLinkTo specifies a DOS application, the ".PIF" extension will be used, otherwise the ".LNK" extension will be used for the shortcut."
А свойства DOS приложения кроме pif файла можно задать в apps.inf файле: "The Apps.inf file in Windows 98 (in the \Windows\Inf directory) contains a section named [PIF95] that acts as a master list of settings for MS-DOS-based applications. Each line in this section corresponds to a subsequent entry in Apps.inf that contains information about running that specific application."
Полное описание есть в MSDN по адресу Resource Kits->Windows 98 Resource Kit->25 — Application Support->Configuring Applications.
Вы безусловно правы — при использовании MFC/ATL данные макросы существенно облегчают жизнь. Просто мой пример сознательно был написан на "чистом" API из соображений универсальности.
У меня вопрос. Иногда (50/50) я не могу получить:
hres = p_shell_link->GetPath(pszPath, MAX_PATH, NULL, SLGP_UNCPRIORITY);//SLGP_RAWPATH
hres содержит какое-то огромное значение, а pszPath — пустая.
Имеется ввиду, раз на раз не приходится, т.е. по непонятным причинам этот метод не всегда срабатывает.
В Release версии, кажется, все работает путем.
Кто-н. сталкивался с таким?
Re[2]: Работа с ярлыками - Проблема в DEBUG версии
Здравствуйте, Krivonos, Вы писали:
K>У меня вопрос. Иногда (50/50) я не могу получить: K>hres = p_shell_link->GetPath(pszPath, MAX_PATH, NULL, SLGP_UNCPRIORITY);//SLGP_RAWPATH K>hres содержит какое-то огромное значение,
получить по нему текстовое описание ошибки не пробовал?
Re[3]: Работа с ярлыками - Проблема в DEBUG версии
Здравствуйте, Krivonos, Вы писали:
OE>>получить по нему текстовое описание ошибки не пробовал? K>Каким макаром? Есть такая функция? Утилита ErrorLookup не помогает
Маленькое дополнение: An Unofficial Guide to the URL File Format. Довольно толковое описание формата файлов *.URL (ярлык интернета). Их можно читать как обычные *.INI файлы...