函数参考


_WinAPI_UpdateResource

添加,删除或替换可移植可执行(PE)文件资源.

#Include <WinAPIEx.au3>
_WinAPI_UpdateResource ( $hUpdate, $sType, $sName, $iLanguage, $pData, $iSize )

参数

$hUpdate _WinAPI_BeginUpdateResource() 返回的模块句柄.
$sType 更新的资源类型. 不是指针, 参数可以是表示资源类型的预定义整数值.
 如果资源类型标识符第一字符是磅符号 (#), 则剩余字符表示一个十进制数的整数.
 例如,字符串 "#258" 代表标识符 258.
 此外,可以使用预定义资源类型 ($RT_*).
$sName 资源的名称. 参数可以是字符串或整数类型 (见上述).
$iLanguage 资源的语言 (LCID).
$pData 被插入到 $hUpdate 资源文件的数据. 如果资源是预定义类型,
 数据必须有效和正确对齐. 请注意,这是原始二进制数据,
 不是由 _WinAPI_LoadIcon(), _WinAPI_LoadString(), 或其它特定资源加载函数提供的数据.
 所有数据,包括字符串或文本必须 为Unicode 格式.
 如果此参数和 $iSize 同为 0, 则删除 $hUpdate 指定的资源文件.
$iSize 指定 $pData 资源数据的字节大小.

返回值

成功: 返回 1.
失败: 返回 0,设置 the @error 为非 0 值.

注意/说明

建议在资源文件没有加载之前调用此函数,
 如果该文件已经加载,也不会导致返回错误
 应用程序可以使用 _WinAPI_UpdateResource() 反复修改资源数据.
 每次 _WinAPI_UpdateResource() 的调用都将添加,删除和替换内部列表, but does
 但实际上并没有将数据写入到文件.
 应用程序必须使用 _WinAPI_EndUpdateResource() 函数写累积的变化.
 如果 $pData is 与 $iSize 同为 0, 则删除 $hUpdate 指定的资源文件.

相关

详情参考

在MSDN中搜索


示例/演示


#Include <APIConstants.au3>
#Include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)

Global Const $sExe = @ScriptDir & '\MyProg.exe'

Global Const $tagICONRESDIR = 'byte Width;byte Height;byte ColorCount;byte Reserved;ushort Planes;ushort BitCount;dword BytesInRes;ushort IconId;'
Global Const $tagNEWHEADER = 'ushort Reserved;ushort ResType;ushort ResCount;' ; & $tagICONRESDIR[ResCount]

Global $hFile, $hUpdate, $tIcon, $pIcon, $sIcon, $tDir, $pDir, $tInfo, $tData, $iSize
Global $Count, $Bytes = 0, $ID = 400, $Error = 1

; 选择图标以更新资源
$sIcon = FileOpenDialog('Select File', @ScriptDir & '\Extras', 'Icon Files (*.ico)', 1 + 2, 'Script.ico')
If Not $sIcon Then
    Exit
EndIf

; 创建简单的可执行文件 (MyProg.exe), 将添加图标到其中
If Not FileCopy(@ScriptDir & '\Extras\MyProg.exe', $sExe) Then
    MsgBox(16, 'Error', 'Unable to copy MyProg.exe or file already exist in the current directory.')
    Exit
EndIf

Do
    ; 开始更新资源
    $hUpdate = _WinAPI_BeginUpdateResource($sExe)
    If @error Then
        ExitLoop
    EndIf
    ; 把 .ico 文件作为原始二进制数据读取到结构中
    $tIcon = DllStructCreate('ushort Reserved;ushort Type;ushort Count;byte[' & (FileGetSize($sIcon) - 6) & ']')
    $pIcon = DllStructGetPtr($tIcon)
    $hFile = _WinAPI_CreateFile($sIcon, 2, 2)
    If Not $hFile Then
        ExitLoop
    EndIf
    _WinAPI_ReadFile($hFile, $pIcon, DllStructGetSize($tIcon), $Bytes)
    _WinAPI_CloseHandle($hFile)
    If Not $Bytes Then
        ExitLoop
    EndIf
    ; 添加 .ico 文件中的所有图标到标识为 400, 401 等的 RT_ICON 资源, 并填充到组图标结构
    $Count = DllStructGetData($tIcon, 'Count')
    $tDir = DllStructCreate($tagNEWHEADER & 'byte[' & (14 * $Count) & ']')
    $pDir = DllStructGetPtr($tDir)
    DllStructSetData($tDir, 'Reserved', 0)
    DllStructSetData($tDir, 'ResType', 1)
    DllStructSetData($tDir, 'ResCount', $Count)
    For $i = 1 To $Count
        $tInfo = DllStructCreate('byte Width;byte Heigth;byte Colors;byte Reserved;ushort Planes;ushort BPP;dword Size;dword Offset', $pIcon + 6 + 16 * ($i - 1))
        $iSize = DllStructGetData($tInfo, 'Size')
        If Not _WinAPI_UpdateResource($hUpdate, $RT_ICON, $ID, 0, $pIcon + DllStructGetData($tInfo, 'Offset'), $iSize) Then
            ExitLoop 2
        EndIf
        $tData = DllStructCreate($tagICONRESDIR, $pDir + 6 + 14 * ($i - 1))
        DllStructSetData($tData, 'Width', DllStructGetData($tInfo, 'Width'))
        DllStructSetData($tData, 'Height', DllStructGetData($tInfo, 'Heigth'))
        DllStructSetData($tData, 'ColorCount', DllStructGetData($tInfo, 'Colors'))
        DllStructSetData($tData, 'Reserved', 0)
        DllStructSetData($tData, 'Planes', DllStructGetData($tInfo, 'Planes'))
        DllStructSetData($tData, 'BitCount', DllStructGetData($tInfo, 'BPP'))
        DllStructSetData($tData, 'BytesInRes', $iSize)
        DllStructSetData($tData, 'IconId', $ID)
        $ID += 1
    Next
    ; 添加新的命名为 "MAINICON" 的 RT_GROUP_ICON 资源
    If Not _WinAPI_UpdateResource($hUpdate, $RT_GROUP_ICON, 'MAINICON', 0, $pDir, DllStructGetSize($tDir)) Then
        Exitloop
    EndIf
    $Error = 0
Until 1

; 保存或放弃可执行文件中资源的修改
If Not _WinAPI_EndUpdateResource($hUpdate, $Error) Then
    $Error = 1
EndIf

; 如果错误发生了则显示消息
If $Error Then
    MsgBox(16, 'Error', 'Unable to change resources.')
EndIf