Як я можу безпосередньо відобразити піктограму з відомим ідентифікатором dll?


1

Хтось знає, як безпосередньо відобразити піктограму у форматі "Реєстр"? Наприклад, "% SystemRoot% \ system32 \ shell32.dll, 112", тобто C: \ Windows \ System32 \ shell32.dll, 112, як правило, є ідентифікатором піктограми, який знаходиться в даних реєстру для значення "IconPath" . Шлях справжній, піктограма "112" - це лише випадкове число.

Справа в тому, що громіздко знайти правильний значок, коли dll складається з сотень значків, навіть коли використовується такий інструмент, як Icon Extractor , який відображатиме інформацію про піктограму, коли курсор наводить курсор на іконки. Усі ці інструменти, здається, функціонують навпаки: треба завантажити dll, наступну надію знайти піктограму з відповідним кодом.

Відповіді:


2

Піктограми для типів файлів - це ресурси (тобто будь-який тип зображення, медіа тощо), вбудовані у відомі DLL-файли. Цей номер значка (або індекс групи значків) не випадковий. У файлах DLL є розділ для зберігання цих ресурсів. Кожна піктограма зберігається з унікальними номерами. Один тип піктограми може складатися з різних розмірів, розмірів і глибини піктограм. Цей ідентифікатор піктограми надходить із групи групи значків, так що коли користувач змінює рівень масштабування, він змінює лише розмір значка, а не сам значок.

Це можна легко зрозуміти на прикладі. У цьому випадку я використовую ресурс хакер . Ось скріншот піктограм файлів із ярликами (розширення .LNK) у Resource Hacker (піктограми можуть відрізнятися):

Resource_Hacker_Shell32

А ось налаштування реєстру:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.lnk\ShellNew]
"Handler"="{ceefea1b-3e29-4ef1-b34c-fec79c4f70af}"
"IconPath"="%SystemRoot%\system32\shell32.dll,-16769"
"ItemName"="@shell32.dll,-30397"
"MenuText"="@shell32.dll,-30318"
"NullFile"=""

Дивіться номер "16769", співставте його із скріншотом. Але як відкрити його в Resource Hacker ? Відповідь: Завантажте та запустіть це програмне забезпечення -> Скопіюйте shell32.dll(або будь-який файл dll / exe) у робочу папку / робочу папку -> перетягніть цей файл у вікно хакерських ресурсів -> Двічі клацніть на «Група значків» -> Прокрутка до цього числа. Дивіться, що в одній групі значків є багато піктограм відповідно до їх розмірів 16x16, 20x20 тощо. Вони призначені для різного масштабу в File Explorer.


0

Складно знайти правильний значок, коли dll складається з сотень іконок

Ви можете використовувати наступний сценарій Powershell .\DisplayIcon.ps1:

<#
.SYNOPSIS
    Exports an ico and bmp file from a given source to a given destination
.Description
    You need to set the Source and Destination locations. First version of a script, I found other examples 
    but all I wanted to do as grab and ico file from an exe but found getting a bmp useful. Others might find useful
.EXAMPLE
    This will run but will nag you for input
    .\Icon_Exporter.ps1
.EXAMPLE
    this will default to shell32.dll automatically for -SourceEXEFilePath
    .\Icon_Exporter.ps1 -TargetIconFilePath 'C:\temp\Myicon.ico' -IconIndexNo 238
.EXAMPLE
    This will give you a green tree icon (press F5 for windows to refresh Windows explorer)
    .\Icon_Exporter.ps1 -SourceEXEFilePath 'C:/Windows/system32/shell32.dll' -TargetIconFilePath 'C:\temp\Myicon.ico' -IconIndexNo 41

.Notes
    Based on http://stackoverflow.com/questions/8435/how-do-you-get-the-icons-out-of-shell32-dll Version 1.1 2012.03.8
    New version: Version 1.2 2015.11.20 (Added missing custom assembly and some error checking for novices)
#>
Param ( 
    [parameter(Mandatory = $true)]
    [string] $SourceEXEFilePath = 'C:/Windows/system32/shell32.dll',
    [parameter(Mandatory = $true)]
    [string] $TargetIconFilePath,
    [parameter(Mandatory = $False)]
    [Int32]$IconIndexNo = 0
)

$code = @"
using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace System
{
    public class IconExtractor
    {

     public static Icon Extract(string file, int number, bool largeIcon)
     {
      IntPtr large;
      IntPtr small;
      ExtractIconEx(file, number, out large, out small, 1);
      try
      {
       return Icon.FromHandle(largeIcon ? large : small);
      }
      catch
      {
       return null;
      }

     }
     [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
     private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);

    }
}
"@

If  (-not (Test-path -Path $SourceEXEFilePath -ErrorAction SilentlyContinue ) ) {
    Throw "Source file [$SourceEXEFilePath] does not exist!"
}

[String]$TargetIconFilefolder = [System.IO.Path]::GetDirectoryName($TargetIconFilePath) 
If  (-not (Test-path -Path $TargetIconFilefolder -ErrorAction SilentlyContinue ) ) {
    Throw "Target folder [$TargetIconFilefolder] does not exist!"
}

Try {
    If ($SourceEXEFilePath.ToLower().Contains(".dll")) {
        Add-Type -TypeDefinition $code -ReferencedAssemblies System.Drawing
        $Icon = [System.IconExtractor]::Extract($SourceEXEFilePath, $IconIndexNo, $true)    
    } Else {
        [void][Reflection.Assembly]::LoadWithPartialName("System.Drawing")
        [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
        $image = [System.Drawing.Icon]::ExtractAssociatedIcon("$($SourceEXEFilePath)").ToBitmap()
        $bitmap = new-object System.Drawing.Bitmap $image
        $bitmap.SetResolution(72,72)
        $icon = [System.Drawing.Icon]::FromHandle($bitmap.GetHicon())
    }
} Catch {
    Throw "Error extracting ICO file"
}

Try {
    $stream = [System.IO.File]::OpenWrite("$($TargetIconFilePath)")
    $icon.save($stream)
    $stream.close()
} Catch {
    Throw "Error saving ICO file [$TargetIconFilePath]"
}
Write-Host "Icon file can be found at [$TargetIconFilePath]"

# Loosely based on http://www.vistax64.com/powershell/202216-display-image-powershell.html

[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")

$img = [System.Drawing.Image]::Fromfile($TargetIconFilePath);

# This tip from http://stackoverflow.com/questions/3358372/windows-forms-look-different-in-powershell-and-powershell-ise-why/3359274#3359274
[System.Windows.Forms.Application]::EnableVisualStyles();
$form = new-object Windows.Forms.Form
$form.Text = "Image Viewer"
$form.Width = $img.Size.Width;
$form.Height =  $img.Size.Height;
$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Width =  $img.Size.Width;
$pictureBox.Height =  $img.Size.Height;

$pictureBox.Image = $img;
$form.controls.add($pictureBox)
$form.Add_Shown( { $form.Activate() } )
$form.ShowDialog()
#$form.Show();

Приклад виводу:

> .\DisplayIcon.ps1 -SourceEXEFilePath 'C:\Windows\system32\shell32.dll' -TargetIconFilePath 'f:\test\Myicon.ico' -IconIndexNo 41
Icon file can be found at [f:\test\Myicon.ico]

введіть тут опис зображення

Примітки:

  • Цей сценарій був створений з використанням перелічених нижче джерел
  • Дякуємо Бену Н у Root Access за допомогу в налагодженні коду.

Джерела:


@WinMike Answer повністю переписаний за допомогою командного рядка рішення Powershell. Насолоджуйтесь!
DavidPostill

@Biswapriyo Ви могли це зробити самі. У вас є достатня кількість представників. Посилання додано.
DavidPostill
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.