Loopback
|
Posted: Fri Jan 22, 2010 22:02 Post subject: |
|
|
Еще вариант, на Autoit+WinAPI. Делал для других целей, но с небольшой модификацией сгодилось и тут.
Code: |
; Параметры: %P <имя dll>
; Требования: Autoit 3.3.4.0 (от 15.01.2010) или выше!
If $CmdLine[0] < 2 Then
MsgBox (64, "", "Необходимо 2 параметра.")
Exit
EndIf
Global Const $RT_ICON = 3
Global Const $RT_GROUP_ICON = 14
Global Const $FILE_BEGIN = 0
Global $nGroup_ID = 1
Global $nIcon_ID = 1
Global $sErrFiles = ""
Global $sSrcDir = $CmdLine[1]
Global $sNewLib = $CmdLine[2]
Dim $bStub = "0x" & _
"4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000" & _
"000000000000000000000000B00000000E1FBA0E00B409CD21B8014CCD21546869732069732033322D62697420726573" & _
"6F7572636520646C6C2E0D0D0A0000000000000000000000240000000000000029E701DB6D866F886D866F886D866F88" & _
"AA8069886C866F8832A465886C866F88526963686D866F880000000000000000504500004C0101000CA3E83A00000000" & _
"00000000E0000F010B010600000000001000000000000000000000000002000000020000000040001000000010000000" & _
"040000000000000004000000000000001002000000020000000000000200000000001000001000000000100000100000" & _
"000000001000000000000000000000000000000000000000000200001000000000000000000000000000000000000000" & _
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _
"000000000000000000000000000000000000000000000000000000000000000000000000000000002E72737263000000" & _
"100000000002000010000000000200000000000000000000000000004000004000000000000000000000000000000000" & _
"000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000"
$hLibFile = FileOpen($sNewLib, 2 + 16)
FileWrite($hLibFile, $bStub)
FileClose($hLibFile)
$aRet = DllCall("kernel32.dll", "int", "BeginUpdateResource", "str", $sNewLib, "int", 1)
If @error Then
MsgBox (0, "", "Не могу открыть библиотеку.")
Exit
EndIf
$hUpdate = $aRet[0]
$hSearch = FileFindFirstFile($sSrcDir & "\*.ico")
While 1
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
$hFile= FileOpen($sSrcDir & "\" & $sFile, 16)
$nReserved = Int(FileRead($hFile, 2))
$nType = Int(FileRead($hFile, 2))
$nSubIcons = Int(FileRead($hFile, 2))
If Not (($nReserved = 0) And ($nType = 1)) Then
$sErrFiles &= $sFile & @CRLF
ContinueLoop
EndIf
$pGroupBuffer = DllStructCreate("byte[" & 6 + $nSubIcons*14 & "]")
$pGroupHeader = DllStructCreate("word;word;word", DllStructGetPtr($pGroupBuffer))
DllStructSetData($pGroupHeader, 1, 0)
DllStructSetData($pGroupHeader, 2, 1)
DllStructSetData($pGroupHeader, 3, $nSubIcons)
For $j = 0 to $nSubIcons - 1
$pBuffer = DllStructCreate("byte[16]")
DllStructSetData($pBuffer, 1, FileRead($hFile, 16))
$pFileIconResInfo = DllStructCreate("byte;byte;byte;byte;word;word;dword;dword", DllStructGetPtr($pBuffer))
$nDataSize = DllStructGetData($pFileIconResInfo, 7)
$nOffset = DllStructGetData($pFileIconResInfo, 8)
$pResourceIconResInfo = DllStructCreate("byte;byte;byte;byte;word;word;dword;word", DllStructGetPtr($pGroupBuffer)+6+14*$j)
For $k = 1 To 7
DllStructSetData($pResourceIconResInfo, $k, DllStructGetData($pFileIconResInfo, $k))
Next
DllStructSetData($pResourceIconResInfo, 8, $nIcon_ID)
$nOldPos = FileGetPos($hFile)
FileSetPos($hFile, $nOffset, $FILE_BEGIN)
$pNewIcon = DllStructCreate("byte[" & $nDataSize & "]")
DllStructSetData($pNewIcon, 1, FileRead($hFile, $nDataSize))
FileSetPos($hFile, $nOldPos, $FILE_BEGIN)
DllCall("kernel32.dll", "int", "UpdateResource", "int", $hUpdate, "int", $RT_ICON, "int", $nIcon_ID, _
"word", 0, "ptr", DllStructGetPtr($pNewIcon), "int", $nDataSize)
$nIcon_ID += 1
Next
DllCall("kernel32.dll", "int", "UpdateResource", "int", $hUpdate, "int", $RT_GROUP_ICON, "int", $nGroup_ID, _
"word", 0, "ptr", DllStructGetPtr($pGroupBuffer), "int", DllStructGetSize($pGroupBuffer))
$nGroup_ID += 1
FileClose($hFile)
WEnd
DllCall("kernel32.dll", "int", "EndUpdateResource", "int", $hUpdate, "int", 0)
If $sErrFiles <> "" Then MsgBox(48, "Внимание!", "Следующие иконки не добавлены (неверный формат?):" & @CRLF & @CRLF & $sErrFiles)
|
|
|