Извлечь значок из файла Windows .lnk (ярлык)

Мне нужно извлечь значок из файла ярлыка Windows (.lnk) (или найти файл значка, если он просто указан ярлыком).

Я не спрашиваю об извлечении значков из exe, dll и т. Д. Соответствующий ярлык создается, когда я запускаю программу установки. И значок, отображаемый ярлыком, не содержится в .exe, на который указывает ярлык. Предположительно значок встроен в файл .lnk, или файл .lnk содержит указатель на то, где находится этот значок. Но ни одна из найденных мною утилит не решает эту проблему - все они просто обращаются к .exe.

Большое спасибо!


person Community    schedule 05.12.2008    source источник


Ответы (6)


В этом потоке содержится интересная информация о данных, содержащихся в файле .lnk

Функция sSHGetFileInfoss должна иметь возможность извлекать файл значка.

Документировано здесь и используется для файла lnk:

Path2Link := 'C:\Stuff\TBear S Saver.lnk';
SHGetFileInfo(PChar(Path2Link), 0, ShInfo1, SizeOf(TSHFILEINFO),
          SHGFI_ICON);
// this ShInfo1.hIcon will have the Icon Handle for the Link Icon with
// the small ShortCut arrow added}

По первой ссылке вы можете создать такую ​​утилиту на C #, где вы бы объявили эту функцию как:

[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(
   string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, 
   uint cbSizeFileInfo, uint uFlags);

Вы также можете создать служебную программу на языке сценариев автоматической установки, где вы будет использовать эту функцию, объявленную так:

Func _ShellGetAssocIcon(Const $szFile,Const $IconFlags = 0)
    Local $tFileInfo = DllStructCreate($tagSHFILEINFO)
    If @error Then
        Return SetError(1,@extended,0)
    EndIf

    Local $Ret = DllCall("shell32.dll","int","SHGetFileInfo","str",$szFile,"dword",0, _
        "ptr",DllStructGetPtr($tFileInfo),"uint",DllStructGetSize($tFileInfo),"uint",BitOr($SHGFI_ICON,$IconFlags))
    MsgBox(0,0,@error)
    Return DllStructGetData($tFileInfo,"hIcon")
EndFunc
person VonC    schedule 05.12.2008
comment
Может быть, дайте ему немного больше информации, например, о формате структуры и т. Д. Но ты получил мой голос. - person Jonathan C Dickinson; 05.12.2008

Используя метод доступа к ссылкам Shell32:

String lnkPath = @"C:\Users\PriceR\Desktop\Microsoft Word 2010.lnk";
//--- run microsoft word
var shl = new Shell32.Shell();         // Move this to class scope
lnkPath = System.IO.Path.GetFullPath(lnkPath);
var dir = shl.NameSpace(System.IO.Path.GetDirectoryName(lnkPath));
var itm = dir.Items().Item(System.IO.Path.GetFileName(lnkPath));
var lnk = (Shell32.ShellLinkObject)itm.GetLink;
//lnk.GetIconLocation(out strIcon);
String strIcon;
lnk.GetIconLocation(out strIcon);
Icon awIcon = Icon.ExtractAssociatedIcon(strIcon);
this.button1.Text = "";
this.button1.Image = awIcon.ToBitmap();
person Robbie    schedule 26.11.2012

В 2010 году Microsoft наконец выпустила официальную спецификацию формата файла LNK. Конечно, он намного точнее и детальнее, чем спецификации, разработанные методом обратной инженерии, распространяющиеся в сети.

Для полноты картины здесь Описание MSDN ссылок и ярлыков оболочки.

person Helge Klein    schedule 26.08.2011

Вы также можете самостоятельно проанализировать файл .lnk, см. этот pdf или эта статья с подробностями о формате файла ярлыков.

Или вы можете использовать класс ShellLink, упомянутый в ответе на этот вопрос.

person Treb    schedule 05.12.2008
comment
обе ссылки мертвые. : / - person Sai Nikhil; 22.11.2013
comment
Ссылка .PDF заархивирована здесь: http://web.archive.org/web/20090408051551/http://www.i2s-lab.com/Papers/The_Windows_Shortcut_File_Format.pdf, а статья находится здесь: http://web.archive.org/web/20110817051855/http://www.stdlib.com/art6-Shortcut-File-Format-lnk.html - person Kevin Fegan; 20.05.2015

Я использую это, чтобы добавить значок без мини-значка со стрелкой в ​​виде изображения:

using IWshRuntimeLibrary;

Image ShortcutIcon = System.Drawing.Icon.ExtractAssociatedIcon(((IWshShortcut)new WshShell().CreateShortcut(File)).TargetPath).ToBitmap();

Если вы хотите получить его в виде значка:

Icon ShortcutIcon = System.Drawing.Icon.ExtractAssociatedIcon(((IWshShortcut)new WshShell().CreateShortcut(File)).TargetPath);
person Remon Ramy    schedule 04.01.2017
comment
Да, у меня это сработало, просто нужно было добавить ссылку на COM-объект Windows Script Host Object Model. - person intrepidis; 16.07.2020
comment
Также по возможности стоит использовать свойство IconLocation объекта ярлыка. - person intrepidis; 16.07.2020

Чтобы добавить к этому еще несколько ресурсов, потому что, вероятно, у вас нет значка приложения, а не значка с ярлыком в левом нижнем углу:

person Chris S    schedule 14.09.2009