一个自动更新自己的程序(非病毒,喜欢就先UP再DOWN) (0分)

  • 主题发起人 主题发起人 shellapi
  • 开始时间 开始时间
S

shellapi

Unregistered / Unconfirmed
GUEST, unregistred user!
好困,刚写完的东东,睡觉去了。
the method to use AUTOUPDATE
TAutoupdate.create(hinstance,'http://www.***.com/shopserver.info','0.9');
如果是在.exe调用,则更新.exe,如果是在.dll中调用,就是更新.dll
unit uautoupdate;
//this unit is used to auto do
wnload and replace a .exe or .dll file
//just call TAutoUpdate.create(hinstance,info_url,cversion)
//hinstance: the module you want to replace
//info_url: an http or ftp url which contain the information of an new version
// the format is: version=... <CR> url=...<CR> filesize=... <CR>
//cversion: current version of the file
interface
uses
Classes,Windows,Urlmon,sysutils,Inifiles,WinINet;
type
TAutoUpdate = class(TThread)
private
finfo_url,fversion,ffilename:string;
protected
procedure Execute;
override;
public
constructor create(hinstance:thandle;info_url,cversion:string);
end;

implementation
function HTTPRequest(const URL:String):string;
var
HFile,HInet: HINTERNET;
Buffer : array[0..32767] of char;
BufRead : Cardinal;
BufSize:Cardinal;
const
Agent = 'Netbar';
begin
HInet := InternetOpen(Agent,INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
result:='';
if Assigned(HInet) then
try
HFile := InternetOpenUrl(HInet, PChar(URL), nil, 0, INTERNET_FLAG_RELOAD+INTERNET_FLAG_KEEP_CONNECTION, 0);
if Assigned(HFile) then
try
BufSize:=SizeOf(Buffer);
while InternetReadFile(HFile, @Buffer, BufSize, BufRead) and (BufRead > 0) do
begin
Buffer[BufRead]:=#0;
result:=result+PChar(@Buffer);
end;
finally
InternetCloseHandle(HFile);
end;
finally
InternetCloseHandle(hinet);
end;
end;

procedure MoveFile(src,dst:string);
var MyIni: TIniFile;
begin
if GetVersion<$80000000 then
// Windows NT/2000/XP
begin
MoveFileEx(Pchar(src),Pchar(dst),MOVEFILE_DELAY_UNTIL_REBOOT);
end else
begin
// Windows 32s/95/98/Me
MyIni := TIniFile.Create('WININIT.INI');
Myini.WriteString('rename',ExtractShortPathName(dst),ExtractShortPathName(src));
MyIni.free;
end;

end;
constructor TAutoUpdate.create(hinstance:thandle;info_url,cversion:string);
var
filename:array[0..MAX_Path] of char;
begin
finfo_url:=info_url;
fversion:=cversion;
getmodulefilename(hinstance,filename,sizeof(filename));
ffilename:=strpas(filename);
inherited create(false);
end;

function Get_FileSize(FileName : String) : Integer;
var
F : THandle;
fSize : DWORD;
begin
//Open up file
F := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL OR FILE_FLAG_NO_BUFFERING, 0);
fSize := GetFileSize(F, nil);
//Get the file's size
CloseHandle(F);
Result :=fsize;
end;

procedure TAutoUpdate.Execute;
var
info:string;
param:TStringList;
newversion,url:string;
begin
info:=httprequest(finfo_url);
param:=TStringlist.Create;
param.Text:=info;
newversion:=param.Values['version'];
if newversion<=fversion then
exit;
url:=param.values['url'];
if S_OK<>urldownloadtofile(nil,pchar(url),pchar(ffilename+'.tmp'),0,nil) then
exit;
if inttostr(Get_FileSize(ffilename+'.tmp'))<>param.values['filesize'] then
exit;
MoveFile(ffilename+'.tmp',ffilename);
end;

end.
 
小巧。收藏。
注: 此UPDATE 必须要重新启动才能完成更新自己的动作
 
我也想搞个自动更新。可我的空间只能放HTML,不知该如何办才好?
解析HTML用哪个控件啊,我一点都不熟悉。(就是传入一个地址参数,返回整个HTML内容的)
thanks
 
这个模块就是针对只能放html的,解析html可以不用控件,好好看看我的代码,
它能告诉你怎么做。
 
非技术问题。哈哈哈
帮你up一下。
 
不错
也还可以改进一下,改成不用重启系统而实现自我更新。
 
xianjun,提提意见,如何卸掉已经装入内存的DLL。这样才不用重启。
 
Unload 内存中的DLL是可以的,当然,相关的程序要关掉,这个你可以通过DLL找到哪些应用
引用了你的DLL,如果没有应用程序引用了你的DLL,但DLL并没有从内存卸载,这时你就可以
手动FreeLibrary直到其引用计数为0. Microsoft有一个DEMO是做这个的,你可以看看:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q96312
 
是自己卸掉自己,不是卸掉其他dll。这个模块是放在要更新的dll中的。
xianjun再提意见。
 
其实我也没有试过,但想来是可以的
1、先取得自己所在模块的文件名
2、枚举系统的模块,找到引用了自己(DLL)的进程,发送关闭信息关闭每个进程
3、检查引用记数,如果不为0则调用FreeLibrary降到0
4、降为0后即已经卸载了。
第3步我是看Microsoft的那个sample里写的,但后来发现居然是win31的,FAINT! 那些
如取得引用记数GetMoudleUsage好象就已经没有了。
 
没有理由不帮你up一下吧。
 
后退
顶部