delphi通过将数据放入EXE的资源信息中的方式制作自已的安装工具


本文整理自网络,侵删。

 

关键点:读取资源,然后使用;如果是动态添加的资源则应该在使用前检查。

 

一、资源导入:在Delphi XE版本中有个工具,可以直接将文件当做资源导入到程序中,编译时会自动编译到资源中去。




 

通过上面的步骤完成资源导入,则工程文件的program下应该多一行{$R *.dres}


二、资源使用
var
  rs: TResourceStream;
begin
  rs := TResourceStream.Create(HInstance, ResName, RT_RCDATA);
  try
    //资源流中可以是图片,文本等数据...
  finally
    rs.Free;
  end;
end;

三、多语言方案

安装包一般是将多种语言集成在一起,由用户选择安装语言,可以先将做一个中文的键值对文件,做为UI字典,通过方法一导入工程中,实现几上公共方法,用于加载字典和翻译:LoadDict,T(Key),这样UI中所有的需要文字描述的地方使用T(Key)的方式取得,以后再添加语言时也无需修改代码。
var
  UIDict: TDictionary<string,string> = nil;//全局变量
  UICurrentLang: string = 'EN';//当前UI语言

procedure LoadUIDict;
var
  rs: TResourceStream;
  sl: TStrings;
  I: Integer;
  UICode: Word;
  UIList: string;
  ResName, sLine: string;
begin
  //从资源中加载语言字典
  if not Assigned(UIDict) then
    UIDict := TDictionary<string,string>.Create;

  sl := TStringList.Create;
  try
    ResName := Format('UIDICT_', [UICurrentLang]);
    rs := TResourceStream.Create(HInstance, ResName, RT_RCDATA);
    try
      sl.LoadFromStream(rs);
      for I := 0 to sl.Count - 1 do
        if sl[I] <> '' then
          UIDict.AddOrSetValue(SL.Names[I], SL.ValueFromIndex[I]);
    finally
      rs.Free;
    end;
  finally
    sl.Free;
  end;
end;


function T(UIKey: string): string;
begin
  //翻译UIKey
  if not UIDict.TryGetValue(UIKey, Result) then
    Result := '(Unknow)';
end;

如果是文本且用于UI,则需要注意尽量使用UTF8对文本或文件进行编码,否则在非中文操作系统环境下会显示乱码。

四、动态添加资源

主要使用以下几个API实现:BeginUpdateResource、UpdateResource、EndUpdateResource
var 
  hrSrc: THandle;
  ResStream: TMemoryStream;
begin

  hrSrc := BeginUpdateResource(PChar(ExeFile), False);//一定是Exe或Dll
  if hrSrc = 0 then
  begin
    ShowMessage('BeginUpdateResource[Error]');
    Exit;
  end;

  //以下这段可以封装并多次使用,比如:添加LOGO图片,添加UI字典,添加程序压缩包等
  ResStream := TMemoryStream.Create;
  try
    ResStream.LoadFromFile('D:\dict_cn.txt');
    ResName := 'UIDICT_CN';//例子
    if not UpdateResource(hrSrc, RT_RCDATA, PChar(ResName), 0, ResStream.Memory, ResStream.Size) then
    begin
      ShowMessage('UpdateResource[Fail]');
      Exit;
    end;
  finally
    ResStream.Free;
  end;

  //将之前更新的资源写回文件中
  if not EndUpdateResource(hrSrc, False) then
  begin
    ShowMessage('EndUpdateResource[Error]');
    Exit;
  end;
end;

function CheckResExists(resList: TArray<string>): Boolean;
var
  hrSrc: THandle;
  resName: string;
begin
  //检查资源ID是否存在,如果是动态添加资源方式,在使用前一定要检查
  Result := False;
  for resName in resList do
  begin
    hrSrc := FindResource(HInstance, PChar(resName), RT_RCDATA);
    if hrSrc = 0 then
      Exit;
    FreeResource(hrSrc);
  end;
  Result := True;
end;

五、高级方案

可以写个控制台的构建工具,比如叫:BuildTool,通过分析配置文件将安装所需的信息动态添加到安装壳程序中

注意事项:如果是添加字符串资源,可以使用TStringStream,并指定编码方式为UTF8或Unicode

 

来源:https://blog.csdn.net/cmd9x/article/details/83655620

相关阅读 >>

Delphi 几个日期操作

Delphi meid校验码算法

Delphiwindows 下编译 exe 文件时把一个外部 txt 文件编译到 exe 里面

Delphi中执行javascript代码

Delphi 把一个ico转换为bmp

Delphi 10 firedac 连接池设置

Delphi vcl 模式下和firemonkey 模式下的字符串

Delphi image 图像清空

Delphi bmp 转换jpg

Delphi wmi 取显卡gpu信息

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...