Cara mengekstrak ikon .ico daripada fail .exe dalam Windows: API, Python dan .NET

Kemaskini terakhir: 09/10/2025
Pengarang Ishak
  • API dari Windows membolehkan anda memperoleh HICON dan membaca piksel dengan GetDIBits (BGRA).
  • En Python, ctypes meliputi ExtractIconExW dan menukar kepada imej dengan Bantal.
  • .NET memudahkan untuk memaparkan ikon yang dikaitkan dengan fail dengan ImageList + ListView.
  • Menguruskan pengendalian GDI dan pesanan saluran untuk mengelakkan kebocoran dan ralat.

Gunakan imej sebagai ikon tersuai untuk folder dalam Windows 11

Jika anda bekerja dalam Windows, lambat laun anda akan mahu mengekstrak ikon daripada fail boleh laku atau .ico untuk digunakan semula dalam apl lain, dalam senarai atau untuk ujian anda. Terdapat beberapa cara untuk melakukan ini dalam ekosistem Windows: API asli (ExtractIconExW, GetDIBits…), Python dengan ctypes, .NET dengan Icon.ExtractAssociatedIcon dan juga penyelesaian veteran dalam Visual Basic klasik. Setiap satu mempunyai nuansa dan kelebihannya. Anda boleh menyemak a Panduan untuk Utiliti NirSoft.

Dalam panduan ini, kami meletakkan semua bahagian itu bersama-sama di satu tempat. Anda akan melihat segala-galanya daripada cara meminta Windows untuk HICON "kecil" dan "besar" yang mendedahkan .exe atau .ico, cara membaca peta bit dalam format BGRA, menukarnya kepada RGBA jika anda memerlukannya untuk PyGame atau Bantal dan cara memaparkan ikon yang dikaitkan dengan fail dalam Windows Forms ListView dengan ImageListKami juga menyemak pendekatan VB klasik untuk menyenaraikan dan menyimpan ikon, dan membincangkan pertimbangan praktikal.

Apa yang ada di dalam .ico dan .exe: saiz dan tempat ia muncul

Satu ikon boleh memasukkan beberapa imej dalaman dengan saiz yang berbeza (16x16, 32x32, 48x48, dsb.). Dalam Windows, adalah perkara biasa untuk apa yang dipanggil ikon “kecil” (16×16) digunakan dalam Windows dan dalam Explorer, di mana cache suka Windows thumbs.db boleh menyimpan lakaran kecil, manakala “besar” (32×32) Ia dipaparkan dalam bar tugas dan apabila anda menogol dengan Alt+Tab. Boleh laku (.exe) dan perpustakaan (.dll) menyimpan ikon sebagai sumber, dan fail .ico sendiri ialah bekas untuk berbilang resolusi dan kedalaman warna.

API Windows menjadikan bacaan ini mudah: dengan ExtractIconExW (At shell32.dll) anda boleh meminta ikon kecil atau besar yang didedahkan oleh fail, sama ada .exe atau .ico. Fungsi itu mengembalikan pemegang HICON sedia untuk dilukis atau, jika anda mahu pergi lebih jauh, ke baca bitmap asas dan memanipulasi piksel.

Jika anda memerlukan bahan mentah (mis. bait peta bit untuk diproses dengan perpustakaan anda sendiri), laluan tersebut termasuk GetIconInfo untuk pergi dari HICON ke HBITMAP anda dan GetDIBits untuk membuang kandungan ke dalam penimbal yang anda kawal. Ini memberi anda kawalan sepenuhnya: saiz tepat, susunan bait, ketelusan dan pemformatan.

Kita mesti mengingati format dalaman yang Windows kembalikan dalam kes ini: biasanya kita sedang berurusan 32 bit setiap piksel dalam BGRA (biru, hijau, merah dan alfa). Perbezaan ini dengan RGBA konvensional adalah penting jika anda bercadang untuk menghantar imej kepada enjin atau perpustakaan yang mengharapkan susunan saluran yang berbeza.

Perkara utama ialah memahami bahawa API mengembalikan data dalam susunan bacaan GDI. Dengan pengepala yang betul dan ketinggian negatif, anda boleh menerima imej masuk atas ke bawah (atas ke bawah) dan dengan itu memudahkan penggunaannya secara langsung di perpustakaan lain tanpa perlu membalikkan penimbal.

saiz ikon dan lokasi dalam Windows

Mengekstrak ikon dengan Python dan Windows API (ctypes): daripada HICON kepada bait imej

Jika anda menggunakan Python pada Windows, laluan paling langsung hari ini ialah tarik ctypes untuk memanggil API asli. Kita boleh memikirkan pywin32, tetapi terdapat perincian penting: pywin32 tidak mendedahkan GetDIBits, dan fungsi itu diperlukan untuk dapatkan piksel sebenar daripada HICON. Oleh itu, ctypes ialah cara praktikal untuk mentakrifkan struktur, prototaip dan panggilan tepat seperti yang diharapkan oleh Windows API.

Urutan biasa adalah seperti berikut: cipta a serasi DC (CreateCompatibleDC), panggil ExtractIconExW Untuk mendapatkan ikon kecil atau besar, selesaikan peta bit warna dan topeng dengan GetIconInfo, sediakan a BITMAPINFO dengan pengepala 32-bit, tunjukkan ketinggian negatif untuk koordinat atas ke bawah, dan akhirnya buang piksel dengan GetDIBits dalam penimbal Python (ctypes.create_string_buffer).

daripada ctypes import byref, sizeof daripada ctypes import c_int, c_void_p daripada ctypes import create_string_buffer daripada ctypes.wintypes import BOOL, BYTE, DWORD, HBITMAP, HDC, HGDIOBJ, HICON, LONG, LPCWSTR, LPVOID, UINT, WORD
import ctypes # Pemalar biasa BI_RGB = 0 DIB_RGB_COLORS = 0 # Struktur minimum untuk kelas GDI ICONINFO(ctypes.Structure): _fields_ = kelas RGBQUAD(ctypes.Structure): _fields_ = kelas BITMAPINFOHEADER(ctypes.Structure =FOuc. _fields_ = # DLLs shell32 = ctypes.WinDLL('shell32', use_last_error=True) user32 = ctypes.WinDLL('user32', use_last_error=True) gdi32 = ctypes.WinDLL('gdi32_er) #kegunaan_lastrutype shell32.ExtractIconExW.argtypes = shell32.ExtractIconExW.restype = UINT user32.GetIconInfo.argtypes = user32.GetIconInfo.restype = BOOL pengguna32.DestroyIcon.argtypes = pengguna32.DestroyIcon.restype = BOOL gCompatible gdi32.CreateCompatibleDC.restype = HDC gdi32.GetDIBits.argtypes = gdi32.GetDIBits.restype = c_int gdi32.DeleteObject.argtypes = gdi32.DeleteObject.restype = BOOL # Penghitungan mudah untuk kelas saiz =2Size IconSize @LARGE: to_wh(size): return {IconSize.SMALL: (16, 16), IconSize.LARGE: (32, 32)} # High-level function (sketch) def extract_icon(filename, size): dc = gdi32.CreateCompatibleDC(0) if dc == 0: #HiconErrors.W/HiconErrors.W/HiconEc mengikut kesesuaian out_large = byref(hicon) jika saiz == IconSize.LARGE else Tiada out_small = byref(hicon) jika saiz == IconSize.SMALL else Tiada yang mendapat = shell32.ExtractIconExW(nama fail, 0, out_large, out_small, 1) jika mendapat != 1: W raise = ICONFORS. user32.GetIconInfo(hicon, byref(info)): user32.DestroyIcon(hicon) tingkatkan ctypes.WinError() w, h = IconSize.to_wh(saiz) bmi = BITMAPINFO() ctypes.memset(byref(bmi), 0, sizeof(bmi.He) bmi sizeof(BITMAPINFOHEADER) bmi.bmiHeader.biWidth = w bmi.bmiHeader.biHeight = -h # negatif untuk atas-bawah bmi.bmiHeader.biPlanes = 1 bmi.bmiHeader.biBitCount = 32 bmi.bmiHeader.GBacompression = w_bmiHeader.GB bmi. * 4 bit = create_string_buffer(bmi.bmiHeader.biSizeImage) disalin = gdi32.GetDIBits(dc, info.hbmColor, 0, h, bits, byref(bmi), DIB_RGB_COLORS) jika disalin == 0: # Pembersihan minimum jikaD: gdihbm2Color.info) info.hbmMask: gdi32.DeleteObject(info.hbmMask) user32.DestroyIcon(hicon) raise ctypes.WinError() # Bersihkan GDI dan HICON if info.hbmColor: gdi32.DeleteObject(info.hbmColor) if info.hbm2.Mask.bele user32.DestroyIcon(hicon) kembali bit # bait BGRA

Dengan di atas, anda kini boleh mendapatkan ikon kecil atau besar mana-mana boleh laku. Sebagai contoh, jika anda ingin mencuba dengan penterjemah Python itu sendiri (laluan tersedia di sys.executable), cuma ekstrak kedua-dua saiz dan gunakan penampannya.

# Contoh penggunaan import sys small_icon = extract_icon(sys.executable, IconSize.SMALL) large_icon = extract_icon(sys.executable, IconSize.LARGE)

Hasilnya ialah blok bait di mana Setiap piksel menduduki 4 bait dalam BGRA. Dalam 16×16 anda akan mempunyai 16×16×4 = 1024 bait, dan dalam 32×32, 4096. Susunan adalah baris demi baris dan lajur demi lajur, dari atas ke bawah dan dari kiri ke kanan jika anda menggunakan ketinggian negatif dalam pengepala, yang memudahkan untuk membaca indeks yang betul untuk setiap (x, y).

  Bagaimana untuk membuka fail PNG dalam Windows 10

Jika anda ingin mengesahkan saiz, anda boleh mencetak panjang penimbal 16x16 dan pastikan ia adalah Bait 1024Semakan ini menyelamatkan anda daripada kejutan apabila bekerja dengan sumber yang merangkumi pelbagai resolusi dan kedalaman warna.

Untuk menggambarkan piksel demi piksel dan menghargai susunan bacaan, satu teknik pengajaran ialah menggunakan PyGame: anda melalui baris penampan demi baris, tukar setiap BGRA kepada RGBA dan cat dengan set_at. Anda juga boleh memperkenalkan kelewatan awal yang kecil kepada "lihat" cara ikon diisi pada skrin.

# Render ikon 32x32 dengan PyGame, tukarkan BGRA -> RGBA daripada import winicon IconSize, extract_icon import pygame import sys pygame.init() skrin = pygame.display.set_mode((320, 240)) icon_size = IconSize.LARGE w, h = IconSize.LARGE w, h = IconSize(i.conto_size) icon extract_icon(sys.executable, icon_size) rendered = False offset_x, offset_y = 50, 50 manakala True: untuk acara dalam pygame.event.get(): if event.type == pygame.QUIT: sys.exit() screen.fill((0, 0, 0))): untuk col dalam julat(*w)): untuk colw dalam julat(*w)): untuk col dalam julat( *w) * 4 b, g, r, a = icon_large color = (r, g, b, a) screen.set_at((offset_x + col, offset_y + row), color) jika tidak diberikan: pygame.time.wait(10) pygame.display.flip() rendered = True

Dalam amalan, anda tidak akan sentiasa mahu mengetik piksel dengan tangan. Untuk menyimpan ikon ke cakera sebagai imej, Bantal (PIL) menjadikan hidup lebih mudah: anda mencipta imej daripada bait dengan mod 'RGBA' yang menunjukkan bahawa input ialah 'BGRA' dan simpan sebagai BMP, PNG atau apa sahaja yang sesuaiPenyesuai seperti win32_icon_to_image(icon_bits, size) memusatkan penukaran itu untuk anda.

# Menukar penimbal BGRA kepada Imej PIL dan menyimpan daripada import PIL Image def win32_icon_to_image(icon_bits, size): w, h = IconSize.to_wh(size) img = Image.frombytes('RGBA', (w, h), icon_bits, 'raw', 'BGRA'_small img win32_icon_to_image(small_icon, IconSize.SMALL) img_large = win32_icon_to_image(large_icon, IconSize.LARGE) img_small.save('python1.bmp') img_large.save('python2.bmp')

Pengekstrakan dengan Python dan Windows API

Paparkan ikon yang dikaitkan dengan fail dalam .NET (WinForms): ListView + ImageList

Satu lagi keperluan biasa ialah untuk menunjukkan, bersama-sama dengan nama setiap fail, fail ikon yang Windows kaitkan dengan sambungannya (contohnya, .docx dengan ikon Word). Dalam WinForms anda boleh menyelesaikannya dengan Ikon.ExtractAssociatedIcon dan menyimpan hasilnya dalam a Senarai Imej yang terikat pada ListView yang ditetapkan kepada paparan SmallIcon.

Ideanya adalah untuk melintasi fail dalam direktori, dan untuk setiap satu semak jika anda sudah mempunyai imej dalam ImageList dengan kunci sama dengan sambungan; jika tidak, ekstrak ikon dan tambahkannya. Macam ni anda mengelakkan pendua dan anda akan mempercepatkan pemuatan. Untuk item ListView, anda tetapkan sifat ImageKey dengan sambungan itu dan tambah item tersebut. Jika sesuatu gagal, anda boleh menggunakan sandaran seperti SystemIcons.WinLogo.

ListView listView1 = new ListView(); ImageList imageList1 = new ImageList(); listView1.SmallImageList = imageList1; listView1.View = View.SmallIcon; // Gelung melalui fail (memerlukan penggunaan System.IO) var dir = new System.IO.DirectoryInfo(@"C:\\"); foreach (fail var dalam dir.GetFiles()) { var item = new ListViewItem(file.Name); kunci var = fail.Sambungan; jika (!imageList1.Images.ContainsKey(key)) { var icon = System.Drawing.Icon.ExtractAssociatedIcon(file.FullName); imageList1.Images.Add(kunci, ikon); } item.ImageKey = kunci; listView1.Items.Add(item); }

Untuk menyusunnya dengan cepat, tampal kod ke dalam a Borang Windows, buat dan konfigurasikan ListView dan ImageList dalam pembina atau dalam acara Muat, dan ingat untuk mengimport ruang nama Sistem.IO. Anda tidak perlu berurusan secara manual dengan HICON atau piksel; di sini anda bergantung sepenuhnya persatuan ikon sistem.

  Bagaimanakah anda mengecas pengawal OLED Nintendo Switch dengan betul?

Pendekatan klasik dengan Visual Basic (extractor/viewer dan simpan ke BMP)

Sebelum .NET dan pembalut moden, banyak utiliti dalam VB 4/5/6 telah melakukan kerja ini dengan memanggil API: ExtractIcon dari shell32 untuk mendapatkan HICON, DrawIcon untuk melukis dalam PictureBox, dan BitBlt untuk menyalin ke permukaan lain dan mencipta jalur lakaran kecil. Program ini menyenaraikan ikon .exe atau .dll dengan menambah indeks ikon sehingga fungsi berhenti mengembalikan hasil.

Aliran biasa ialah: selepas memilih fail, mulakan pada indeks 0 dan, sementara ExtractIcon kembalikan pemegang yang sah, lukiskannya dalam PictureBox, muat semula dan pindah ke indeks seterusnya. Secara selari, dengan BitBlt, 32x32 telah disalin ke permukaan kedua pada kedudukan mengimbangi (cth., ke X = 2 + indeks × sel) ke lihat semua ikon terbenam sepintas lalu.

Untuk menyimpan, VB menawarkan dua laluan dengan SavePicture: simpan sifat Gambar sebagaimana adanya atau sifat Imej (yang terakhir sentiasa sebagai BMP). Selain itu, beberapa borang menambah pemilih fail dengan penapis mengikut sambungan untuk .ico, .bmp, .exe, .dll dan lain-lain, malah menunjukkan pratonton jika fail itu ialah imej.

Pendekatan ini masih sah untuk memahami cara berinteraksi dengan API daripada bahasa Windows "tradisional". Walau bagaimanapun, jika anda memerlukan API hari ini, penampan piksel, adalah lebih baik untuk menggunakan GDI dan GetDIBits (atau, dalam .NET moden, kaedah yang menyerikan imej) daripada hanya bergantung pada DrawIcon tentang kawalan.

Butiran penting: saiz, susunan bait dan bacaan baris/lajur

Apabila mendapatkan semula piksel dengan GetDIBits, menentukan biHeight sebagai negatif menjadikan asal koordinat sudut kiri atas, itulah yang diharapkan oleh banyak perpustakaan grafik. Jika anda tidak, anda akan mendapat a penimbal bawah ke atas (bawah ke atas) dan anda perlu menyongsangkan blok mengikut baris.

Dalam 16×16, baris pertama menduduki 16×4 = Bait 64 (4 setiap piksel). Oleh itu, anjakan ke baris n ialah n × 64 dan ke lajur m ialah m × 4. Dalam 32 × 32, setiap baris ialah Bait 128 dan jumlahnya ialah 4096. Pesanan BGRA (B, G, R, A) ialah apa yang GDI panggil pulangan; jika perpustakaan sasaran anda mahukan RGBA, anda perlu melakukannya menyusun semula saluran seperti yang dilakukan dengan PyGame atau nyatakan apabila mencipta imej dengan Bantal.

  Ketahui cara membetulkan kegagalan pengawal status kuasa dalam tetingkap rumah House 10

Jika anda memanipulasi ketelusan, saluran alfa akan menjadi bait keempat piksel. Ingat bahawa ikon juga menggunakan a topeng (hbmMask); apabila bekerja dengan BGRA 32-bit, ketelusan biasanya sudah diwakili dalam alfa hbmColor, jadi topeng boleh diabaikan untuk kegunaan biasa.

Ikon dalam Sumber dan Penggantian: Pertimbangan Pantas

Boleh laku dan perpustakaan menyimpan ikon mereka sebagai sumberAnda boleh mengekstraknya dengan API seperti yang dijelaskan atau, jika anda lebih suka sesuatu yang visual, terdapat editor sumber dan utiliti dengan antara muka grafik yang membolehkan anda berbuat demikian. menggantikan atau mengeksport ikon. Jika anda akan mengautomasikan, pendekatan program dengan HICON, GetIconInfo dan GetDIBits memberikan anda kawalan dan kebolehulangan sepenuhnya.

Untuk membaca ikon "yang dikaitkan" dengan sambungan (tanpa mengekstrak sumber daripada .exe itu sendiri), .NET memudahkan kerja dengan Ikon.ExtractAssociatedIcon. Kaedah ini bergantung pada persatuan pendaftaran dan mengembalikan ikon yang sistem akan paparkan untuk setiap fail, yang sesuai untuk senarai, peneroka dan penonton.

Amalan baik dan pembersihan sumber

Bekerja dengan GDI melibatkan pengurusan pemegang dan ingatan secara eksplisit. Setiap kali anda memperoleh HICON atau HBITMAP anda mesti meramalkan kitaran hayatnya: musnahkan HICON dengan MusnahIcon dan lepaskan peta bit dengan DeleteObject. Melupakannya boleh menyebabkan kehilangan sumber yang, dalam aplikasi dengan banyak panggilan, diterjemahkan ke dalam kebocoran dan tingkah laku yang tidak menentu.

Dalam Python/ctypes adalah mudah untuk merangkum pembersihan dalam fungsi kecil atau a pengurus konteks. Pastikan anda sentiasa menjalankan pembersihan pada cawangan pepijat, terutamanya jika GetDIBits mengembalikan 0 atau ya ExtractIconExW tidak mengembalikan bilangan ikon yang dijangkakan. Juga, sahkan bahawa DC yang dikembalikan oleh CreateCompatibleDC adalah sah sebelum meneruskan.

Bila hendak memilih setiap pendekatan

Jika anda hanya perlu memaparkan ikon "yang akan dipaparkan oleh Windows" untuk fail, .NET dengan ExtractAssociatedIcon Ia mudah dan berkesan. Kalau nak baca bitmap sebenar daripada ikon yang dibenamkan dalam .exe atau .ico untuk mengedit, menukar atau menyimpannya sendiri, the API dengan ctypes Ia memberi anda semua kawalan yang anda perlukan. Untuk alatan warisan atau prototaip pantas, pendekatan VB klasik kekal sebagai ilustrasi dan berfungsi dalam konteksnya.

Sebaliknya, jika matlamatnya adalah untuk menyimpan ikon sebagai imej dengan lapisan alfa dan tanpa kehilangan, pertimbangkan format seperti PNG Menggunakan Bantal, menyediakan pesanan saluran yang sesuai. BMP adalah mudah dan disokong secara meluas, tetapi jika anda lebih suka pemampatan dan ketelusan, PNG atau ICO (jika pembungkusan semula) mungkin lebih sesuai.

Dengan menyepadukan Native API, Python dan .NET, anda boleh merangkumi segala-galanya daripada kes mudah memaparkan ikon yang dikaitkan dengan sambungan kepada mengekstrak BGRA bait Dengan kawalan penuh ke atas saiz, ketelusan dan susunan bacaan, serta keupayaan untuk menyenaraikan ikon yang dibenamkan dalam boleh laku legasi atau moden. Pelbagai laluan ini akan membolehkan anda menyelesaikan segala-galanya daripada penonton dan penyenaraian kepada eksport ikon dan saluran paip penyuntingan.

Utiliti NirSoft-5
artikel berkaitan:
Panduan Terbaik untuk Utiliti NirSoft: Lebih 250 Alat Percuma untuk Memperbaik Windows