将内嵌资源经过HASH校验后释放或覆盖外部文件
By
admin
at 2022-10-26 • 0人收藏 • 905人看过
有这么一个场景:
软件中把dll和ini文件都内嵌进去了, 这样当客户运行exe的时候自动释放dll和ini到appdata目录中 , 客户用了几天之后.
我们发现之前写的dll里面有bug , 那么需要把新的dll重新打包进exe , 因为appdata目录是隐藏的, 不可能让客户自己去删除原来的dll , 这样就需要运行exe的时候自动释放更新这个dll , 但是不能每次打开exe都去删除之前的释放新的, 这样不合理 , 那么就需要自动判断是否需要更新那个dll 了,
流程方法如下:
判断目录里有没有那个dll , 没有说明第一次运行exe , 立马释放dll过去
如果目录里已经存在那个dll , 获取原来dll的哈希值, 和我们exe里面的dll的哈希值比较, 如果相同则说明是最新的,不用更新. 如果不同 , 那么说明原来目录里是旧的需要更新
更新:
经过老大指点 , 如果是释放到appdata目录, 那么可以直接使用io.appData即可
io.appData("\popdes\配置\sys.ini",string.load("\配置\sys.ini"));
该函数可以比较文件大小和时间戳, 如果不同则自动保存覆盖文件.
这种方式比下面使用HASH值校验速度快的多.
注意:
如果需要把文件释放到其他目录, 或者有不需要每次强制校验更新的文件
那么可以参考io.appData的实现代码自己封装个函数.
我简单封装了个函数, 有需要的看2楼
以下是我之前编写的旧HASH校验代码, 仅用来记录
import fsys;
import crypt;
var fileRelease = function(releasePath,resPath){
if(!io.exist(releasePath)){
//不存在,释放
var str = string.load(resPath);
string.save(releasePath, str);
}else {
//计算旧文件的哈希值
var oldstr = string.load(releasePath);
var oldHASH = crypt().hash(oldstr);
//计算内嵌文件的哈希值
var newstr = string.load(resPath);
var newHASH = crypt().hash(newstr);
//比较两个文件哈希值
if(oldHASH !== newHASH){
//文件需更新,则释放
string.save(releasePath, newstr);
}
}
}
fileRelease(io.appData("\popdes\demo.dll"),"\res\demo.dll");
fileRelease(io.appData("\popdes\配置\sys.ini"),"\配置\sys.ini");
4 个回复 | 最后更新于 2022-11-21
登录后方可回帖
有时候可能需要释放到其他目录, 而不是appData 那么就将代码
简单封装成了一个通用库 , 增加了是否需要强制校验 , 可以释放到任意目录.
默认:true=每次运行都强制校验, 不相同就删掉并更新
false=只要文件存在即可, 不强制和内嵌文件完全相同
更新:
如楼上所述可以使用io.appData(p,d)可直接释放并校验到appData里, 原理是获取文件的大小和时间戳进行对比校验, 那么我们查看io.appData的实现代码, 然后把我之前写的库给修改下, 提高执行速度. , 库可以改为以下代码:
//释放内嵌文件 namespace releaseFile{ run = function(releasePath,resPath,update=true){ if(!..io.exist(releasePath)){ //不存在,释放 ..string.save(releasePath,..string.load(resPath)); }else { if(!update){ //不需要校验, 只要有文件存在就放行 return; } //比较长度和时间戳 var d = ..string.load(resPath); var e; var f = ..io.open(releasePath,"rb"); if(f){ e = f.size()==#d; if(e && (d[1]+d[2]==0xA7) ){ var a = ..raw.convert(d,{INT v},60).v + 8; f.seek("set",a); e = f.read({INT v})[["v"]]===..raw.convert(d,{INT v},a).v; } f.close(); } if(!e){ ..string.save(releasePath,d); } } } } /**intellisense() releaseFile = 内嵌文件释放 releaseFile.run(.(外部文件路径,内嵌资源路径,强制校验) = 执行内嵌文件释放 end intellisense**/使用方法是一样的
import releaseFile; releaseFile.run(io.appData("\popdes\demo.dll"),"\res\demo.dll"); releaseFile.run(io.appData("\popdes\配置\sys.ini"),"\配置\sys.ini",false);以下是我之前编写的旧HASH校验代码, 仅用来记录
//释放内嵌文件 import crypt; namespace releaseFile{ run = function(releasePath,resPath,update=true){ if(!..io.exist(releasePath)){ //不存在,释放 var str = ..string.load(resPath); ..string.save(releasePath, str); }else { if(!update){ //不需要校验, 只要有文件存在就放行 return; } //计算旧文件的哈希值 var oldstr = ..string.load(releasePath); var oldHASH = ..crypt().hash(oldstr); //计算内嵌文件的哈希值 var newstr = ..string.load(resPath); var newHASH = ..crypt().hash(newstr); //比较两个文件哈希值 if(oldHASH !== newHASH){ //文件需更新,则释放 ..string.save(releasePath, newstr); } } } } /**intellisense() releaseFile = 内嵌文件释放 releaseFile.run(.(外部文件路径,内嵌资源路径,强制校验) = 执行内嵌文件释放 end intellisense**/使用方法:
import releaseFile; releaseFile.run(io.appData("\popdes\demo.dll"),"\res\demo.dll"); releaseFile.run(io.appData("\popdes\配置\sys.ini"),"\配置\sys.ini",false);