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

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

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

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

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);

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

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

используя За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();

вы также можете разобрать .файл LNK см. этот pdf или в этой статье о деталях формата файла ярлыка.

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


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

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


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


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

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);