Извлечь значок из файла Windows .lnk (ярлык) - PullRequest
7 голосов
/ 05 декабря 2008

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

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

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

Ответы [ 6 ]

6 голосов
/ 27 ноября 2012

Использование метода 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();
6 голосов
/ 05 декабря 2008

Эта ветка предоставляет интересную информацию о данных , содержащихся в файле .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
2 голосов
/ 26 августа 2011

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

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

1 голос
/ 05 декабря 2008

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

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

0 голосов
/ 04 января 2017

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

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);
0 голосов
/ 14 сентября 2009

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

...