Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Вытащить из .exe или .dll иконку

Ответить
Настройки темы
[решено] Вытащить из .exe или .dll иконку

Пользователь


Сообщения: 62
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изменения
Автор: assch
Дата: 07-07-2010
Пытаюсь сделать небольшую програмку которая меняет иконки у папок. В Windows такая утилитка есть ,только работает она
с файлами .ico а информацию записывает в .ini файл , и соответственно при разрыве путей (Например файл .ico перешёл в другое место
или папку вообще перенесли на другой компьютер) Вид папки примет обычный вид. Смысл програмки такой - Файл .ico копируется в папку назначения
и в ней же создаётся файл .ini где прописывается путь к этой иконке ,эти два файла можно сделать не видимыми. Поэтому при переносе этой папки
на другой компьютер она будет иметь вид той иконки которая вшита в ней. Проектик сами понимаете не комерческий а просто ради интереса что-то
сделать самому.
С простыми файлами .ico это сделать просто, а вот если кому-то пондравится иконка зашитая в .exe или .dll. Я понимаю что можно
вытащить эту иконку с помощью какой нибудь програмки но хочется чтобы работало всё в одном флаконе. Скажем при выборе иконки для папки
выбираешь файл .exe или .dll в окне отображаются все иконки зашитые в ней ( Сделать это просто, пример даже есть в Autoit ) дальше при выборе самой иконки из этого списка
нужно вытащить её из этих файлов в формате .ico ну а дальше всё просто.
По информации которую я пытаюсь найти вертится это около функции API ExtractIconExW хотя могу и ошибатся.

Вопрос - можно ли это сделать силами Autoit или нет?
Буду признателен любой инфрмации.

Отправлено: 22:07, 06-07-2010

 

Аватара для FlatX007

Ветеран


Сообщения: 553
Благодарности: 87

Профиль | Отправить 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



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Аватара для Creat0R

Must AutoIt


Moderator


Сообщения: 3035
Благодарности: 1000

Профиль | Сайт | Отправить PM | Цитировать


Цитата assch:
можно ли это сделать силами Autoit »
Можно:

Код: Выделить весь код
#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

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

Русское сообщество AutoIt | CreatoR's Lab | Opera AC Community

Это сообщение посчитали полезным следующие участники:

Отправлено: 01:22, 07-07-2010 | #3


Аватара для beve

Старожил


Сообщения: 307
Благодарности: 137

Профиль | Отправить PM | Цитировать


Вложения
Тип файла: rar Script.rar
(8.0 Kb, 59 просмотров)

Вот есть такой скрипт...

-------
Не в кількості знань полягає освіта, а в повному розумінні і вмілому використанні того, що знаєш.


Последний раз редактировалось beve, 07-07-2010 в 02:39.

Это сообщение посчитали полезным следующие участники:

Отправлено: 02:22, 07-07-2010 | #4


Пользователь


Сообщения: 62
Благодарности: 0

Профиль | Отправить PM | Цитировать


Большое всем спасибо, жалко только что функция _FileExtractIcon делает это хорошо, и код довольно компактный ,только иконки на выходе получаются на чёрном фоне .
Всё равно всем большое спасибо за информацию .
Старожилу beve особенно за подарок.
Уважаемому Creat0R за интересный код , попробую понять почему получаются такие иконки.

Последний раз редактировалось assch, 07-07-2010 в 20:32.


Отправлено: 03:40, 07-07-2010 | #5


Аватара для Creat0R

Must AutoIt


Moderator


Сообщения: 3035
Благодарности: 1000

Профиль | Сайт | Отправить 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

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

Русское сообщество AutoIt | CreatoR's Lab | Opera AC Community

Это сообщение посчитали полезным следующие участники:

Отправлено: 05:11, 07-07-2010 | #6


Пользователь


Сообщения: 62
Благодарности: 0

Профиль | Отправить PM | Цитировать


Да этот код хоть и по обьёмней но гораздо лучше справляется со своей задачей
Большое спасибо Creat0R
Извиняюсь что не в тему
Не подскажете в чём проблема у меня стояла старая версия - autoit-v3.2.4.9 - А недавно обновил до версии autoit-v3.3.6.1 и мои старые файлы
не открываются выскакивает ошибка
Не посоветуйте оптимальную версию или проблема не в этом?

Последний раз редактировалось assch, 07-07-2010 в 20:33.


Отправлено: 13:45, 07-07-2010 | #7


Аватара для madmasles

Ветеран


Сообщения: 815
Благодарности: 353

Профиль | Отправить PM | Цитировать


assch,
Посмотрите здесь: Объявления и новости.
Там Creat0R подробно и по-русски расписал все изменения в версиях, начиная с AutoIt v3.3.1.2 (бета).
Это сообщение посчитали полезным следующие участники:

Отправлено: 14:22, 07-07-2010 | #8


Пользователь


Сообщения: 62
Благодарности: 0

Профиль | Отправить PM | Цитировать


Спасибо madmasles
За быстрый ответ без лишнего этикета

Отправлено: 20:31, 07-07-2010 | #9


Аватара для Creat0R

Must AutoIt


Moderator


Сообщения: 3035
Благодарности: 1000

Профиль | Сайт | Отправить PM | Цитировать


Цитата assch:
Извиняюсь что не в тему »
Извинение не делает это лигитимным
На будущее, если у вас возникают несколько вопросов, пишите в отдельные темы каждый из них, если конечно в поиске не нашли подобной темы.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

Русское сообщество AutoIt | CreatoR's Lab | Opera AC Community

Это сообщение посчитали полезным следующие участники:

Отправлено: 21:50, 07-07-2010 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Вытащить из .exe или .dll иконку

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Как вытащить файлы из **.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




 
Переход