如何修改以下代码中的buffer
,然后保存可执行文件资源中的更改?我正在寻找类似 SetString(handle,index,buffer,size)
的内容。
var
hExe : Cardinal;
buffer : array [0..4097] of ansichar;
begin
hExe:=LoadLibraryEx(PAnsiChar(Edit2.Text),0,LOAD_LIBRARY_AS_DATAFILE);
LoadString(hExe,65300,buffer,SizeOf(buffer));
ShowMessage(buffer);
//need to modify buffer here then I'll unload the resources..
end;
更新:这是我对 UpdateResource 的尝试
var
hEXE: DWORD;
pData: PAnsiChar;
begin
pData := PAnsiChar(Edit1.Text);
hEXE := BeginUpdateResource(pchar(edit2.text), FALSE);
if hEXE <> 0 then
begin
UpdateResource(hEXE, RT_string, MAKEINTRESOURCE(4082), LANG_NEUTRAL,
@pData, Length(pData)); //if i change 4082 to 65300 it creates another key like 4082
EndUpdateResource(hEXE, FALSE);
end;
这段代码搞乱了整个 4082 内容。问题是 RT_STRING 中名为 4082 的项目是字符串组。当我在资源编辑器中打开 exe 时,单击字符串表,然后单击 4082,结果是:
STRINGTABLE
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
{
65296, "Unicode"
65297, "Big Endian Unicode"
65298, "UTF-8"
65299, "UTF-7"
65300, "ABCDE12345"
}
所以我要么需要解析字符串组,要么需要一个 API 来设置组中索引为 65300 的修改字符串。有什么想法吗?
最佳答案
我找到了the answer使用谷歌。 (English translation from Chinese)无论如何谢谢大家!
procedure UpdateResString(AFileName, ANewString: string; AStringIdent: Integer);
procedure WriteToArray(AArray: TByteDynArray; AData: Word; var APos: Integer);
begin
AArray[APos] := Lo(AData);
AArray[APos + 1] := Hi(AData);
Inc(APos, 2);
end;
function ReadFromArray(AArray: TByteDynArray; APos: Integer): Word;
begin
Result := AArray[APos] + AArray[APos + 1] * 16;
end;
var
hModule, hResInfo, hUpdate: THandle;
ResData, TempData: TByteDynArray;
wsNewString: WideString;
iSection, iIndexInSection: Integer;
i, iLen, iSkip, iPos: Integer;
begin
hModule := LoadLibrary(PChar(AFileName));
if hModule = 0 then
raise Exception.CreateFmt('file %s failed to load.', [AFileName]);
// Calculate the resource string area and the string index in that area
iSection := AStringIdent div 16 + 1;
iIndexInSection := AStringIdent mod 16;
// If the resource already exists, then read it out of the original data
hResInfo := FindResource(hModule, MakeIntResource(iSection), RT_STRING);
if hResInfo <> 0 then
begin
iLen := SizeOfResource(hModule, hResInfo);
SetLength(ResData, iLen);
CopyMemory(ResData, LockResource(LoadResource(hModule, hResInfo)), iLen);
end;
// Should first close the file, and then update
FreeLibrary(hModule);
// Calculate the new data is written to location
wsNewString := WideString(ANewString);
iLen := Length(wsNewString);
iPos := 0;
for i := 0 to iIndexInSection do
begin
if iPos > High(ResData) then
SetLength(ResData, iPos + 2);
if i <> iIndexInSection then
begin
iSkip := (ReadFromArray(ResData, iPos) + 1) * 2;
Inc(iPos, iSkip);
end;
end;
// Delete the original data and the data behind the temporary
// storage of data to be added
iSkip := (ReadFromArray(ResData, iPos) + 1) * 2;
TempData := Copy(ResData, iPos + iSkip, Length(ResData) - iSkip);
SetLength(ResData, iPos);
SetLength(ResData, iPos + (iLen + 1) * 2 + Length(TempData));
// Write new data
WriteToArray(ResData, iLen, iPos);
for i := 1 to iLen do
WriteToArray(ResData, Ord(wsNewString[i]), iPos);
// Write back to the original data
for i := 0 to High(TempData) do
ResData[iPos + i] := TempData[i];
// Write the data back to file
hUpdate := BeginUpdateResource(PChar(AFileName), False);
if hUpdate = 0 then
raise Exception.CreateFmt(
'cannot write file %s. Please check whether it is open or set read-only.',
[AFileName]);
UpdateResource(hUpdate, RT_STRING, MakeIntResource(iSection), LANG_NEUTRAL,
ResData, Length(ResData));
EndUpdateResource(hUpdate, False);
end;
关于delphi - 修改exe资源中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1498658/