Работа с ярлыками
От: Илья Зарецкий Россия http://zarezky.spb.ru/
Дата: 31.03.04 06:43
Оценка: 300 (8) -1
Статья:
Работа с ярлыками. Чтение и изменение свойств, создание новых ярлыков.
Автор(ы): Илья Зарецкий
Дата: 31.03.2004
В статье рассматривается предоставляемый Windows механизм программного доступа к ярлыкам (shortcuts) — реализуемые COM-классом ShellLink интерфейсы IShellLink и IPersistFile, методы которых позволяют читать и изменять свойства уже существующих ярлыков, а также создавать новые ярлыки.


Авторы:
Илья Зарецкий

Аннотация:
В статье рассматривается предоставляемый Windows механизм программного доступа к ярлыкам (shortcuts) — реализуемые COM-классом ShellLink интерфейсы IShellLink и IPersistFile, методы которых позволяют читать и изменять свойства уже существующих ярлыков, а также создавать новые ярлыки.
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Работа с ярлыками
От: algol Россия about:blank
Дата: 31.03.04 09:52
Оценка: 8 (3)
Здравствуйте, Илья Зарецкий, Вы писали:

ИЗ>Аннотация:

ИЗ>В статье рассматривается предоставляемый 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 > 1000

class 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 interfaces
    if(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);
}
Re[2]: Работа с ярлыками
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 31.03.04 11:11
Оценка: +3
Здравствуйте, algol, Вы писали:

A>Обычно программисты вместо изучения теории предпочитают просто взять готовый для употребления класс.


Гх-м-м... дабы не ставить под сомнение ни чью профессиональную квалификацию, не буду приводить примеры постов, причиной появления которых является именно подобный подход. А вообще, это вечный спор из серии "нужно ли знать устройство автомобиля, чтобы его водить" — тема ИМХО очень флеймовая.

A>Который и предлагается вашему вниманию.


А вот за это — спасибо.
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Работа с ярлыками
От: siv Украина  
Дата: 01.04.04 08:36
Оценка:
Здравствуйте, Илья Зарецкий, Вы писали:

ИЗ>Статья:



ИЗ>Авторы:

ИЗ> Илья Зарецкий

ИЗ>Аннотация:

ИЗ>В статье рассматривается предоставляемый Windows механизм программного доступа к ярлыкам (shortcuts) — реализуемые COM-классом ShellLink

shortcuts — это, конечно, хорошо... Но вот кто знает, как программно можно создать такой "анахронизм", как pif-файл к старому досовскому приложению (разумеется, задав специфические настройки этого pif-файла) ?
Я однажды перерых MSDN и так ничего вразумительного не обнаружил
Re[2]: Работа с ярлыками
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 01.04.04 08:47
Оценка:
Здравствуйте, siv, Вы писали:

siv>shortcuts — это, конечно, хорошо... Но вот кто знает, как программно можно создать такой "анахронизм", как pif-файл к старому досовскому приложению (разумеется, задав специфические настройки этого pif-файла) ?


А что будет, если программно создать шорткат на ДОСовую прогу?
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[2]: Работа с ярлыками
От: algol Россия about:blank
Дата: 01.04.04 10:03
Оценка:
Здравствуйте, 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.
Re: Работа с ярлыками - маленькое дополнение
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 26.05.04 08:27
Оценка:
Сегодня однаружил на CP класс — CShortcut. Вроде бы как неплохой.
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Работа с ярлыками: T2COLE
От: Аноним  
Дата: 17.06.04 10:31
Оценка:
Здравствуйте, Илья Зарецкий, Вы писали:

// загружаем ярлык
#if defined(_UNICODE)
   ppf->Load(pszShortcut, STGM_READ);
#else
   LPWSTR pwszTemp = new WCHAR[_MAX_PATH];
   mbstowcs(pwszTemp, pszShortcut, _MAX_PATH);
   ppf->Load(pwszTemp, STGM_READ);
   delete[] pwszTemp;
#endif


Вот здесь:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfcnotes_tn059.asp
TN059: Using MFC MBCS/Unicode Conversion Macros

прочел, что, вроде, можно вышеуказанное преобразование в вашей программе написать так:
(макросы описаны в AFXPRIV.H)

USES_CONVERSION;
ppf->Load(T2COLE(pszShortcut), STGM_READ);


А вообще ваша статья мне очень понравилась и, как начинающему, очень помогла.
Жду комментариев или поправок.

granitv, настройщик 1С
Re[2]: Работа с ярлыками: T2COLE
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 17.06.04 11:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вот здесь:

А>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfcnotes_tn059.asp
А>TN059: Using MFC MBCS/Unicode Conversion Macros

А>прочел, что, вроде, можно вышеуказанное преобразование в вашей программе написать так:

А>(макросы описаны в AFXPRIV.H)

А>
А>USES_CONVERSION;
ppf->>Load(T2COLE(pszShortcut), STGM_READ);
А>


Вы безусловно правы — при использовании MFC/ATL данные макросы существенно облегчают жизнь. Просто мой пример сознательно был написан на "чистом" API из соображений универсальности.
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Работа с ярлыками - Проблема в DEBUG версии
От: Krivonos Украина  
Дата: 09.07.04 11:36
Оценка:
У меня вопрос. Иногда (50/50) я не могу получить:
hres = p_shell_link->GetPath(pszPath, MAX_PATH, NULL, SLGP_UNCPRIORITY);//SLGP_RAWPATH
hres содержит какое-то огромное значение, а pszPath — пустая.
Имеется ввиду, раз на раз не приходится, т.е. по непонятным причинам этот метод не всегда срабатывает.
В Release версии, кажется, все работает путем.
Кто-н. сталкивался с таким?
Re[2]: Работа с ярлыками - Проблема в DEBUG версии
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 09.07.04 12:56
Оценка:
Здравствуйте, Krivonos, Вы писали:

K>У меня вопрос. Иногда (50/50) я не могу получить:

K>hres = p_shell_link->GetPath(pszPath, MAX_PATH, NULL, SLGP_UNCPRIORITY);//SLGP_RAWPATH
K>hres содержит какое-то огромное значение,

получить по нему текстовое описание ошибки не пробовал?
Re[3]: Работа с ярлыками - Проблема в DEBUG версии
От: Krivonos Украина  
Дата: 09.07.04 13:16
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>получить по нему текстовое описание ошибки не пробовал?


Каким макаром? Есть такая функция? Утилита ErrorLookup не помогает
Re[4]: Работа с ярлыками - Проблема в DEBUG версии
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 09.07.04 13:24
Оценка:
Здравствуйте, Krivonos, Вы писали:

OE>>получить по нему текстовое описание ошибки не пробовал?

K>Каким макаром? Есть такая функция? Утилита ErrorLookup не помогает

а какой код?
Re: Работа с ярлыками
От: aGrey Литва  
Дата: 09.07.04 16:26
Оценка:
Маленькое дополнение: An Unofficial Guide to the URL File Format. Довольно толковое описание формата файлов *.URL (ярлык интернета). Их можно читать как обычные *.INI файлы...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.