如何使用Delphi读取磁盘上独立于.exe的.res资源文件?
读取独立.res资源文件的正确实现
你的问题出在TResourceStream根本没有CreateFromStream这个构造方法——它的设计目标是读取已加载到进程中的模块(比如EXE、DLL)里的资源,没法直接解析独立的.res文件(这是资源编译后的中间格式,不是可直接加载的资源模块)。
要读取独立.res文件里的指定资源,你可以用TResourceReader来解析.res文件的内容,然后提取对应的资源流。下面是修正后的代码:
function LoadResourceFromDisk(const FileName, ResName: string): TStream; var FileStream: TFileStream; ResReader: TResourceReader; ResEntry: TResourceEntry; begin Result := nil; FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try ResReader := TResourceReader.Create(FileStream); try // 遍历资源条目,找到目标资源 for ResEntry in ResReader.Entries do begin if ResEntry.Name = ResName then begin Result := TMemoryStream.Create; try ResEntry.Data.Position := 0; Result.CopyFrom(ResEntry.Data, ResEntry.Data.Size); Result.Position := 0; except Result.Free; raise; end; Break; end; end; finally ResReader.Free; end; finally FileStream.Free; end; end;
补充说明
TResourceReader在System.Resources单元里(Delphi XE及以后版本可用),专门用来解析.res文件的结构。- 如果你的Delphi版本比较旧,也可以用
LoadLibraryEx把.res文件加载为临时模块,再用TResourceStream读取:
function LoadResourceFromDisk(const FileName, ResName: string): TStream; var hModule: HMODULE; ResStream: TResourceStream; begin Result := nil; // 加载.res文件为临时模块,LOAD_LIBRARY_AS_DATAFILE表示不执行代码 hModule := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE); if hModule <> 0 then try ResStream := TResourceStream.Create(hModule, ResName, RT_RCDATA); // 根据资源类型调整RT_*常量 try Result := TMemoryStream.Create; Result.CopyFrom(ResStream, ResStream.Size); Result.Position := 0; finally ResStream.Free; end; finally FreeLibrary(hModule); end; end;
注意这种方法需要你明确资源的类型(比如RT_RCDATA、RT_BITMAP等),如果不确定资源类型,可能需要枚举模块里的资源来查找。
内容的提问来源于stack exchange,提问作者Douglas Ruiz
相关产品推荐
相关产品推荐

