Как мне манипулировать значком для существующего ярлыка на рабочем столе, используя Win32?

Я хочу иметь возможность получить текущий файл .ico, используемый для ярлыка, а затем временно изменить его на другой файл .ico. Я планировал вручную проанализировать файлы .lnk, но подумал, что сначала можно попросить более простой способ.

1

Решение

Использовать IShellLink интерфейс. Вот примеры из MSDN:

Shell Links

// 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 - 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;
}

В вашем случае вы бы:

  1. Создать экземпляр IShellLink

  2. запросить это для IPersistFile()

  3. вызов IPersistFile.Load() установить .lnk имя файла

  4. вызов IShellLink.Resolve() загрузить файл

  5. вызов IShellLink.SetIconLocation() установить новый .ico имя файла

  6. Вызов IPersistFile.Save() сохранить новый .lnk файл.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]