|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Вытащить из .exe или .dll иконку |
|
[решено] Вытащить из .exe или .dll иконку
|
Пользователь Сообщения: 62 |
Профиль | Отправить PM | Цитировать
Пытаюсь сделать небольшую програмку которая меняет иконки у папок. В Windows такая утилитка есть ,только работает она
с файлами .ico а информацию записывает в .ini файл , и соответственно при разрыве путей (Например файл .ico перешёл в другое место или папку вообще перенесли на другой компьютер) Вид папки примет обычный вид. Смысл програмки такой - Файл .ico копируется в папку назначения и в ней же создаётся файл .ini где прописывается путь к этой иконке ,эти два файла можно сделать не видимыми. Поэтому при переносе этой папки на другой компьютер она будет иметь вид той иконки которая вшита в ней. Проектик сами понимаете не комерческий а просто ради интереса что-то сделать самому. С простыми файлами .ico это сделать просто, а вот если кому-то пондравится иконка зашитая в .exe или .dll. Я понимаю что можно вытащить эту иконку с помощью какой нибудь програмки но хочется чтобы работало всё в одном флаконе. Скажем при выборе иконки для папки выбираешь файл .exe или .dll в окне отображаются все иконки зашитые в ней ( Сделать это просто, пример даже есть в Autoit ) дальше при выборе самой иконки из этого списка нужно вытащить её из этих файлов в формате .ico ну а дальше всё просто. По информации которую я пытаюсь найти вертится это около функции API ExtractIconExW хотя могу и ошибатся. Вопрос - можно ли это сделать силами Autoit или нет? Буду признателен любой инфрмации. |
|
Отправлено: 22:07, 06-07-2010 |
Ветеран Сообщения: 553
|
Профиль | Отправить PM | Цитировать Тут http://bogdan.at.ua/reshack/index.html
ResHack pаботает через командную строку, следовательно им можно управлять по средствам AUTOIT Или тут http://autoit-script.ru/index.php?topic=47.0 Смотреть функции: _WinAPI_LoadResource _WinAPI_LoadLibrary |
Отправлено: 01:19, 07-07-2010 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Must AutoIt Сообщения: 3054
|
Профиль | Сайт | Отправить PM | Цитировать Цитата assch:
#include <GDIPlus.au3> #include <WinAPI.au3> _FileExtractIcon("shell32.dll", @DesktopDir & "\Icon.ico", -20) Func _FileExtractIcon($sSrcFileIcon, $sOutFileIcon, $iIndex = 0) Local $aRet, $hIcon, $pBitmapdll, $pBitmap If $iIndex < 0 Then $iIndex = ($iIndex * -1) EndIf $aRet = DllCall("shell32.dll", "long", "ExtractAssociatedIcon", "int", 0, "str", $sSrcFileIcon, "int*", $iIndex - 1) $hIcon = $aRet[0] _GDIPlus_Startup() $pBitmapdll = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromHICON", "ptr", $hIcon, "int*", 0) $pBitmap = $pBitmapdll[2] _WinAPI_DestroyIcon($hIcon) _GDIPlus_ImageSaveToFileEx($pBitmap, $sOutFileIcon, "{557CF400-1A04-11D3-9A73-0000F81EF32E}") _GDIPlus_ImageDispose($pBitmap) _GDIPlus_Shutdown() Return 1 Endfunc |
|
------- Отправлено: 01:22, 07-07-2010 | #3 |
Старожил Сообщения: 307
|
Профиль | Отправить PM | Цитировать Вот есть такой скрипт...
|
------- Последний раз редактировалось beve, 07-07-2010 в 02:39. Отправлено: 02:22, 07-07-2010 | #4 |
Пользователь Сообщения: 62
|
Профиль | Отправить PM | Цитировать Большое всем спасибо, жалко только что функция _FileExtractIcon делает это хорошо, и код довольно компактный ,только иконки на выходе получаются на чёрном фоне .
Всё равно всем большое спасибо за информацию . Старожилу beve особенно за подарок. Уважаемому Creat0R за интересный код , попробую понять почему получаются такие иконки. |
|
Последний раз редактировалось assch, 07-07-2010 в 20:32. Отправлено: 03:40, 07-07-2010 | #5 |
Must AutoIt Сообщения: 3054
|
Профиль | Сайт | Отправить PM | Цитировать Цитата assch:
Мне удалось выдрать код из примера в посте от beve (кстати этот код вроде взят отсюда), и привести его немного в порядок: #include <WinAPI.au3> Global $aEN[1] $sSrc = @SystemDir & "\shell32.dll" $sOut = @DesktopDir & "\MyIcon.ico" _FileExtractIcon($sSrc, -20, $sOut) Func _FileExtractIcon($sINFILE, $iICON, $sOUTICO, $iPATH = 0, $iSaveAsPng = 0) Local Const $RT_GROUP_ICON = 14 Local $hINST, $iGN = "", $HFIND, $aSIZE, $hLOAD, $HLOCK, $TRES, $sDATA, $aRet[2] If Not FileExists($sINFILE) And Not IsPtr($sINFILE) Then Return SetError(1, 0, 0) If Not IsInt($iICON) Then Return SetError(2, 0, 0) If IsPtr($sINFILE) Then $hINST = $sINFILE Else $hINST = _WinAPI_LoadLibraryEx($sINFILE, 2) If Not $hINST Then Return SetError(3, 0, 0) EndIf If Not IsPtr($hINST) Then Return SetError(3, 0, 0) __ResourceEnumNames($hINST, $RT_GROUP_ICON) If @error Then _WinAPI_FreeLibrary($hINST) Return SetError(4, 0, 0) EndIf For $I = 1 To $aEN[0] If $I = StringReplace($iICON, "-", "") Then $iGN = $aEN[$I] ExitLoop EndIf Next If $iGN = "" Then _WinAPI_FreeLibrary($hINST) Return SetError(5, 0, 0) EndIf $HFIND = DllCall("kernel32.dll", "int", "FindResourceA", "int", $hINST, "str", $iGN, "long", $RT_GROUP_ICON) If $HFIND[0] = 0 Then _WinAPI_FreeLibrary($hINST) Return SetError(6, 0, 0) EndIf $aSIZE = DllCall("kernel32.dll", "dword", "SizeofResource", "int", $hINST, "int", $HFIND[0]) If $aSIZE[0] = 0 Then _WinAPI_FreeLibrary($hINST) Return SetError(7, 0, 0) EndIf $hLOAD = DllCall("kernel32.dll", "int", "LoadResource", "int", $hINST, "int", $HFIND[0]) If $hLOAD[0] = 0 Then _WinAPI_FreeLibrary($hINST) Return SetError(8, 0, 0) EndIf $HLOCK = DllCall("kernel32.dll", "int", "LockResource", "int", $hLOAD[0]) If $HLOCK[0] = 0 Then _WinAPI_FreeLibrary($hINST) Return SetError(9, 0, 0) EndIf $TRES = DllStructCreate("byte[" & $aSIZE[0] & "]", $HLOCK[0]) If Not IsDllStruct($TRES) Then _WinAPI_FreeLibrary($hINST) Return SetError(10, 0, 0) EndIf $sDATA = DllStructGetData($TRES, 1) If $sDATA = "" Then _WinAPI_FreeLibrary($hINST) Return SetError(11, 0, 0) EndIf __FreeResource($hLOAD[0]) If Not IsPtr($sINFILE) Then _WinAPI_FreeLibrary($hINST) Dim $aEN[1] $aRet[0] = $sINFILE $aRet[1] = $sDATA ;_Exticondata() Local $aID = $aRet Local Const $RT_ICON = 3 Local $hINST, $AHDR, $aRet[1][2] If Not IsArray($aID) Then Return SetError(1, 0, 0) If Not FileExists($aID[0]) And Not IsPtr($aID[0]) Then Return SetError(2, 0, 0) If IsPtr($aID[0]) Then $hINST = $aID[0] Else $hINST = _WinAPI_LoadLibraryEx($aID[0], 2) If Not $hINST Then Return SetError(3, 0, 0) EndIf If Not IsPtr($hINST) Then Return SetError(3, 0, 0) $aRet[0][0] = Dec(__Rb(StringMid($aID[1], 11, 4))) ReDim $aRet[$aRet[0][0] + 1][2] $AHDR = StringRegExp(StringTrimLeft(BinaryMid($aID[1], 7), 2), "(.{28})", 3) For $I = 1 To $aRet[0][0] Local $AGID = __GetIconData($hINST, Dec(__Rb(StringRight($AHDR[$I - 1], 4)))) $aRet[$I][0] = StringTrimRight($AHDR[$I - 1], 4) $aRet[$I][1] = $AGID[1] __FreeResource($AGID[0]) Next If Not IsPtr($aID[0]) Then _WinAPI_FreeLibrary($hINST) ;_Createiconfile($aID, $aSEL, $sOUTICO, $iPATH = 0, $iSaveAsPng = 0) Local $aSEL = $iICON $aID = $aRet If Not IsArray($aID) Then Return SetError(1, 0, 0) Local $iCNT, $sHDR, $OFFSET, $sDBYTE, $iMICON = "", $FO, $FW, $eSEL[$aID[0][0]], $iCRT = 18 If $iPATH <> 0 Then $iCRT = 26 If Not IsArray($aSEL) Then For $I = 0 To UBound($eSEL) - 1 $eSEL[$I] = $I + 1 Next $aSEL = $eSEL EndIf If UBound($aSEL) = 1 And StringInStr(StringTrimLeft($aID[$aSEL[0]][1], 2), "504E47") Then If $iSaveAsPng Then $sOUTICO = StringReplace($sOUTICO, ".ico", ".png") EndIf $iCNT = UBound($aSEL) $sHDR = "0x00000100" & __Rb(Hex($iCNT, 4)) $OFFSET = ($iCNT * 16) + 6 For $I = 0 To UBound($aSEL) - 1 $sDBYTE = Dec(__Rb(StringMid($aID[$aSEL[$I]][0], 17, 8))) $sHDR &= $aID[$aSEL[$I]][0] & __Rb(Hex($OFFSET)) $OFFSET += $sDBYTE If StringRight($sOUTICO, 4) = ".png" Then $sHDR = "" $iMICON &= $aID[$aSEL[$I]][1] Else $iMICON &= StringTrimLeft($aID[$aSEL[$I]][1], 2) EndIf Next $FO = FileOpen($sOUTICO, $iCRT) If $FO = -1 Then Return SetError(2, 0, 0) $FW = FileWrite($FO, $sHDR & $iMICON) If $FW = 0 Then FileClose($FO) Return SetError(3, 0, 0) EndIf FileClose($FO) Return SetError(0, 0, 1) EndFunc Func __FreeResource($HGLBRESOURCE) DllCall("kernel32.dll", "int", "FreeResource", "int", $HGLBRESOURCE) EndFunc Func __GetIconData($hMODULE, $iON) Local Const $RT_ICON = 3 Local $HFIND, $aSIZE, $hLOAD, $HLOCK, $TRES, $aRet[2] $HFIND = DllCall("kernel32.dll", "int", "FindResourceA", "int", $hMODULE, "str", "#" & $iON, "long", $RT_ICON) $aSIZE = DllCall("kernel32.dll", "dword", "SizeofResource", "int", $hMODULE, "int", $HFIND[0]) $hLOAD = DllCall("kernel32.dll", "int", "LoadResource", "int", $hMODULE, "int", $HFIND[0]) $HLOCK = DllCall("kernel32.dll", "int", "LockResource", "int", $hLOAD[0]) $TRES = DllStructCreate("byte[" & $aSIZE[0] & "]", $HLOCK[0]) $aRet[0] = $HLOCK[0] $aRet[1] = DllStructGetData($TRES, 1) Return $aRet EndFunc Func __Rb($sBYTE) Local $AX = StringRegExp($SBYTE, "(.{2})", 3), $SX = "" For $I = UBound($AX) - 1 To 0 Step -1 $SX &= $AX[$I] Next Return $SX EndFunc Func __ResourceEnumNames($hMODULE, $iTYPE) Local $aRet, $stCB If Not IsPtr($hMODULE) Then Return SetError(1, 0, 0) $stCB = DllCallbackRegister("__ResourceEnumNames_Proc", "int", "int_ptr;int_ptr;int_ptr;int_ptr") $aRet = DllCall("kernel32.dll", "int", "EnumResourceNamesW", "ptr", $hMODULE, "int", $iTYPE, "ptr", DllCallbackGetPtr($stCB), "ptr", 0) DllCallbackFree($stCB) If $aRet[0] <> 1 Then Return SetError(2, 0, 0) Return SetError(0, 0, 1) EndFunc Func __ResourceEnumNames_Proc($hMODULE, $pTYPE, $pNAME, $lPARAM) Local $aSIZE = DllCall("kernel32.dll", "int", "GlobalSize", "ptr", $pNAME), $tBUF If $aSIZE[0] Then $tBUF = DllStructCreate("wchar[" & $aSIZE[0] & "]", $pNAME) ReDim $aEN[UBound($aEN) + 1] $aEN[0] += 1 $aEN[UBound($aEN) - 1] = DllStructGetData($tBUF, 1) Else ReDim $aEN[UBound($aEN) + 1] $aEN[0] += 1 $aEN[UBound($aEN) - 1] = "#" & $pNAME EndIf Return 1 EndFunc |
|
------- Отправлено: 05:11, 07-07-2010 | #6 |
Пользователь Сообщения: 62
|
Профиль | Отправить PM | Цитировать Да этот код хоть и по обьёмней но гораздо лучше справляется со своей задачей
Большое спасибо Creat0R Извиняюсь что не в тему Не подскажете в чём проблема у меня стояла старая версия - autoit-v3.2.4.9 - А недавно обновил до версии autoit-v3.3.6.1 и мои старые файлы не открываются выскакивает ошибка Не посоветуйте оптимальную версию или проблема не в этом? |
Последний раз редактировалось assch, 07-07-2010 в 20:33. Отправлено: 13:45, 07-07-2010 | #7 |
Ветеран Сообщения: 812
|
Профиль | Отправить PM | Цитировать assch,
Посмотрите здесь: Объявления и новости. Там Creat0R подробно и по-русски расписал все изменения в версиях, начиная с AutoIt v3.3.1.2 (бета). |
Отправлено: 14:22, 07-07-2010 | #8 |
Пользователь Сообщения: 62
|
Профиль | Отправить PM | Цитировать Спасибо madmasles
За быстрый ответ без лишнего этикета |
Отправлено: 20:31, 07-07-2010 | #9 |
Must AutoIt Сообщения: 3054
|
Профиль | Сайт | Отправить PM | Цитировать Цитата assch:
На будущее, если у вас возникают несколько вопросов, пишите в отдельные темы каждый из них, если конечно в поиске не нашли подобной темы. |
|
------- Отправлено: 21:50, 07-07-2010 | #10 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Как вытащить файлы из **.tib или вылечить образ | starl | Хочу все знать | 24 | 12-01-2016 14:38 | |
CMD/BAT - [решено] Как создать ярлык и поменять его иконку или поменять иконку уже существующего ярлыка | Centrinar | Скриптовые языки администрирования Windows | 6 | 04-09-2011 10:56 | |
Для чего нужны dll библиотеки или Учимся редактировать dll | Ban_vam_Dam | Флейм | 5 | 31-07-2009 17:41 | |
Не опознается hal.dll,ntoskrnl.exe,KDCOM.DLL | Igor_strelka | Microsoft Windows 2000/XP | 3 | 12-01-2007 23:23 | |
вытащить текст из EXE | Pallot | Хочу все знать | 8 | 09-10-2006 12:56 |
|