programing

shell32.dll에서 아이콘을 어떻게 끄집어내나요?

closeapi 2023. 9. 28. 08:25
반응형

shell32.dll에서 아이콘을 어떻게 끄집어내나요?

홈그로우 앱에 사용할 트리 아이콘을 받고 싶습니다..icon 파일로 이미지를 추출하는 방법을 아는 사람이 있습니까?저는 16x16과 32x32 둘 다 원합니다, 아니면 그냥 화면 캡처를 하고 싶습니다.

쉬운 방법을 찾고 있는 사람이 있다면 7zip을 사용하여 shell32.dll의 압축을 풀고 폴더 .src/ICON/을 찾아보세요.

Visual Studio에서 "파일 열기..."를 선택합니다." "파일..."을 선택합니다.그런 다음 Shell32.dll을 선택합니다.폴더 트리를 열면 아이콘이 "아이콘" 폴더에 있습니다.

아이콘을 저장하려면 폴더 트리에서 아이콘을 마우스 오른쪽 단추로 클릭하고 "내보내기"를 선택할 수 있습니다.

리소스 해커(ResourceHacker)와 같은 도구를 사용하는 것도 방법입니다.아이콘 이상의 기능도 제공합니다.건배!

제가 100% 맞았는지는 확실하지 않지만 테스트 결과 7Zip 또는 VS를 사용하는 위의 옵션은 Windows 10/11 버전의 imageres.dll 또는 shell32.dll에서 작동하지 않습니다.이 내용은 다음과 같습니다.

[shell32.dll]
.rsrc\MANIFEST\124
.rsrc\MUI\1
.rsrc\TYPELIB\1
.rsrc\version.txt
.data
.didat
.pdata
.rdata
.reloc
.text
CERTIFICATE

업데이트: 그리고 이유를 찾은 것 같습니다.찾은 기사 링크(도메인 밖에 있어서 죄송합니다)파일에서 리소스를 찾을 수 있는 위치는 다음과 같습니다.

"C:\Windows\SystemResources\shell32.dll.mun"
"C:\Windows\SystemResources\imageres.dll.mun"

Windows 10 1903의 dll - 4kb 파일(superuser.com )에서 아이콘이 더 이상 imageres에 없습니다.

shell32.dll에서 아이콘 #238을 추출해야 했고 Visual Studio나 Resourcehacker를 다운로드하고 싶지 않았기 때문에 Technet에서 몇 개의 PowerShell 스크립트를 찾았습니다(John Grenfell과 #https://social.technet.microsoft.com/Forums/windowsserver/en-US/16444c7a-ad61-44a7-8c6f-b8d619381a27/using-icons-in-powershell-scripts?forum=winserverpowershell) 에서 비슷한 작업을 수행하고 필요에 맞는 새 스크립트(below)를 만들어 주셔서 감사합니다).

입력한 매개 변수는 다음과 같습니다(소스 DLL 경로, 대상 아이콘 파일 이름 및 DLL 파일 내 아이콘 인덱스).

C:\Windows\시스템32\shell32.dll

C:\Temp\Restart.ico

238

필요한 아이콘 인덱스는 임시로 새로운 바로가기를 만들어 시행착오를 거쳐 #238임을 알게 되었습니다(바탕화면에서 마우스 오른쪽 버튼을 클릭하고 새로 만들기 --> 바로가기를 선택한 후 계산을 입력하고 Enter 키를 두 번 누릅니다).그런 다음 새 바로 가기를 마우스 오른쪽 단추로 클릭하고 속성을 선택한 다음 바로 가기 탭에서 '아이콘 변경' 버튼을 클릭합니다.경로 C에 붙여넣기:\Windows\System32\shell32.dll을 클릭하고 OK(확인)를 클릭합니다.사용하고 싶은 아이콘을 찾아서 색인을 만듭니다.NB: 색인 2번은 1번 아래에 있고 오른쪽에 있지 않습니다.아이콘 인덱스 #5가 Windows 7 x64 컴퓨터에서 열 2의 맨 위에 있었습니다.

비슷한 방식으로 작동하지만 더 높은 품질의 아이콘을 얻을 수 있는 더 좋은 방법이 있다면 듣고 싶습니다.고마워, 숀.

#Windows PowerShell Code###########################################################################
# http://gallery.technet.microsoft.com/scriptcenter/Icon-Exporter-e372fe70
#
# AUTHOR: John Grenfell
#
###########################################################################

<#
.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
   No error checking I'm afraid so make sure your source and destination locations exist!
.EXAMPLE
    .\Icon_Exporter.ps1
.Notes
        Version HISTORY:
        1.1 2012.03.8
#>
Param ( [parameter(Mandatory = $true)][string] $SourceEXEFilePath,
        [parameter(Mandatory = $true)][string] $TargetIconFilePath
)
CLS
#"shell32.dll" 238
If ($SourceEXEFilePath.ToLower().Contains(".dll")) {
    $IconIndexNo = Read-Host "Enter the icon index: "
    $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())
}
$stream = [System.IO.File]::OpenWrite("$($TargetIconFilePath)")
$icon.save($stream)
$stream.close()
Write-Host "Icon file can be found at $TargetIconFilePath"

리소스 추출(Resources Extract)은 많은 DLL, 매우 편리한 IMO에서 아이콘을 재귀적으로 찾을 수 있는 또 다른 도구입니다.

IrfanView로 DLL을 열고 결과를 .gif 또는 .jpg로 저장하기만 하면 됩니다.

이 질문이 오래된 것은 알지만 "dll에서 아이콘 추출"의 두 번째 구글 히트입니다. 워크스테이션에 설치하는 것을 피하고 싶었고 IrfanView를 사용했던 것을 기억했습니다.

위 솔루션의 업데이트된 버전입니다.링크에 묻힌 누락된 어셈블리를 추가했습니다.초보자들은 그것을 이해하지 못할 것입니다.이 샘플은 수정 없이 실행됩니다.

    <#
.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
)

#https://social.technet.microsoft.com/Forums/windowsserver/en-US/16444c7a-ad61-44a7-8c6f-b8d619381a27/using-icons-in-powershell-scripts?forum=winserverpowershell
$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
        $form = New-Object System.Windows.Forms.Form
        $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]"

프리웨어 리소스 해커를 다운로드한 다음 아래 지침을 따를 수 있습니다.

  1. 아이콘을 찾으려는 dll 파일을 엽니다.
  2. 폴더를 찾아 특정 아이콘을 찾습니다.
  3. 메뉴 모음에서 'action'을 선택한 다음 'save'를 선택합니다.
  4. .ico 파일의 대상을 선택합니다.

참조 : http://techsultan.com/how-to-extract-icons-from-windows-7/

비주얼 스튜디오 이미지 라이브러리(Visual Studio Image Library)라는 리소스도 사용할 수 있습니다. 이 리소스는 "Microsoft 소프트웨어와 시각적으로 일치하는 애플리케이션을 만드는 데 사용할 수 있으며, 아마도 하단에 부여된 라이센스에 따를 것입니다.https://www.microsoft.com/en-ca/download/details.aspx?id=35825

이 을 처음 하여 , 7Zip 로 %SystemRoot%\system32\SHELL32.dll\.rsrc\ICON했습니다.

미리 추출된 디렉토리를 원하시면, ZIP을 여기서 다운받으시면 됩니다.

참고: Windows 8.1 설치에서 파일을 추출했기 때문에 다른 버전의 Windows 파일과 다를 수 있습니다.

Linux를 사용하는 경우 gExtractWinIcon으로 Windows DLL에서 아이콘을 추출할 수 있습니다.Ubuntu와 Debian에서 사용할 수 있습니다.gextractwinicons

이 블로그 기사는 스크린샷과 간단한 설명이 있습니다.

다음은 도서관에서 아이콘을 추출하는 기능을 사용한다는 짜증씨의 답변과 유사한 내용입니다.주요 차이점은 이 기능이 Windows PowerShell 5.1과 PowerShell 7+ 두 가지와 호환되어야 하며 주어진 인덱스에서 기본적으로 큰 아이콘과 작은 아이콘을 추출한다는 것입니다.-InconIndex 이 2)를 출력합니다. 이 기능은 2를 출력합니다.FileInfo(instance)스e)에-DestinationFolder PowerShell (. PowerShell 됩니다()로$pwd).

function Invoke-ExtractIconEx {
    [CmdletBinding(PositionalBinding = $false)]
    param(
        [Parameter()]
        [ValidateNotNull()]
        [string] $SourceLibrary = 'shell32.dll',

        [Parameter(Position = 0)]
        [string] $DestinationFolder = $pwd.Path,

        [Parameter(Position = 1)]
        [int] $InconIndex
    )

    $refAssemblies = @(
        [Drawing.Icon].Assembly.Location

        if ($IsCoreCLR) {
            $pwshLocation = Split-Path -Path ([psobject].Assembly.Location) -Parent
            $pwshRefAssemblyPattern = [IO.Path]::Combine($pwshLocation, 'ref', '*.dll')
            (Get-Item -Path $pwshRefAssemblyPattern).FullName
        }
    )

    Add-Type -AssemblyName System.Drawing
    Add-Type '
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.Drawing;
    using System.IO;

    namespace Win32Native
    {
        internal class SafeIconHandle : SafeHandle
        {
            [DllImport("user32.dll")]
            private static extern bool DestroyIcon(IntPtr hIcon);

            public SafeIconHandle() : base(IntPtr.Zero, true) { }

            public override bool IsInvalid
            {
                get
                {
                    return handle == IntPtr.Zero;
                }
            }

            protected override bool ReleaseHandle()
            {
                return DestroyIcon(handle);
            }
        }

        public static class ShellApi
        {
            [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            private static extern uint ExtractIconExW(
                string szFileName,
                int nIconIndex,
                out SafeIconHandle phiconLarge,
                out SafeIconHandle phiconSmall,
                uint nIcons);

            private static void ExtractIconEx(string fileName, int iconIndex, out SafeIconHandle iconLarge,
                out SafeIconHandle iconSmall)
            {
                if (ExtractIconExW(fileName, iconIndex, out iconLarge, out iconSmall, 1) == uint.MaxValue)
                {
                    throw new Win32Exception();
                }
            }

            public static FileInfo[] ExtractIcon(string sourceExe,
                string destinationFolder, int iconIndex)
            {
                SafeIconHandle largeIconHandle;
                SafeIconHandle smallIconHandle;

                ExtractIconEx(sourceExe, iconIndex, out largeIconHandle, out smallIconHandle);

                using (largeIconHandle)
                using (smallIconHandle)
                using (Icon largeIcon = Icon.FromHandle(largeIconHandle.DangerousGetHandle()))
                using (Icon smallIcon = Icon.FromHandle(smallIconHandle.DangerousGetHandle()))
                {
                    FileInfo[] outFiles = new FileInfo[2]
                    {
                        new FileInfo(Path.Combine(destinationFolder, string.Format("{0}-largeIcon-{1}.bmp", sourceExe, iconIndex))),
                        new FileInfo(Path.Combine(destinationFolder, string.Format("{0}-smallIcon-{1}.bmp", sourceExe, iconIndex)))
                    };

                    largeIcon.ToBitmap().Save(outFiles[0].FullName);
                    smallIcon.ToBitmap().Save(outFiles[1].FullName);

                    return outFiles;
                }
            }
        }
    }
    ' -ReferencedAssemblies $refAssemblies

    $DestinationFolder = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($DestinationFolder)
    [Win32Native.ShellApi]::ExtractIcon($SourceLibrary, $DestinationFolder, $InconIndex)
}

용도:

# Extracts to PWD
Invoke-ExtractIconEx -InconIndex 1

# Targeting a different library
Invoke-ExtractIconEx -SourceLibrary user32.dll -InconIndex 1

# Using a different target folder
Invoke-ExtractIconEx path\to\my\folder -InconIndex 1

언급URL : https://stackoverflow.com/questions/8435/how-do-you-get-the-icons-out-of-shell32-dll

반응형