Delphi开发更新程序(调用WebService)

刚毕业找了个软件公司,到公司找老大接了第一个任务:写一个更新程序,用来更新公司产品的客户端。本人水平实在有限,还好大学读的是“百度专业” ,最后勉强做了个Setup.exe出来。现在把涉及到的知识点记录在这里,希望对刚入行的朋友们(我!)有帮助。

IDE:Delphi 7

1、调用Web Service(C#)

导入WSDL:在你建立的工程里点File->New->Other->WebService->WebService Importer,然后按提示一步步来。

如何获得WSDL地址:如果老大给了你一个URL,可以访问他写的WS,那么只需要在这个URL上加'?wsdl'就是WSDL地址了。

如果要调用的WS需要传递参数,则需要在默认模式下产生的WSDL文件内initialization部分加一句:
InvRegistry.RegisterInvokeOptions(TypeInfo(????Soap), ioDocument);

使用WebSeriver里的THTTPRIO控件,在需要调用WS的程序段,
声明变量 a:????Soap,
然后初始化 a := HTTPRIO1 as ????Soap;
这样就可以直接用 a.WebMethodName();来调用了。

2、Http方式下载:
使用IdHTTP控件

IdHTTP采用阻塞方式(瞎掰的:)
表现结果为:当不使用多线程技术把下载的任务独立出来,那么开始下载时程序将无法响应任何操作,除非下载完成。
所以有时候你需要使用一个到多个小小的线程来做这些事情。如果你恰巧和某人(我!)一样不了解多线程技术,那么有个好消息就是,我花了大概7个小时从0开始搞定了这个问题,当然不涉及复杂的多线程设计、同步什么的。毕竟我们只需要满足任务要求就OK了,如果那些知识需要深入了解,可以稍候再学。

一下是利用IdHTTP的功能,写的一个自定义函数。

procedureTForm1.HttpDownLoad(aURL,aFile:string;bResume:Boolean);
var
tStream:TFileStream;
FileTarget:string;
DirList:TStringList;
tmpCurrectTestDir:String;
i:integer;
begin
//´´½¨È«Â·¾¶Îļþ¼Ð
FileTarget:=aFile;
DirList:=SplitString(FileTarget,'');
tmpCurrectTestDir:=tmpCurrectTestDir+DirList[0]+'';
fori:=1toDirList.count-2do
begin
tmpCurrectTestDir:=tmpCurrectTestDir+DirList[i]+'';
ifnotDirectoryExists(tmpCurrectTestDir)then
CreateDirectory(Pchar(tmpCurrectTestDir),nil);
end;
ifnotThread1.Terminatedthen
begin
try
//Èç¹ûÎļþÒÑ´æÔÚ
ifFileExists(aFile)then
begin
tStream:=TFileStream.Create(aFile,fmOpenWrite);
IdHTTP1.Request.ContentRangeStart:=0;
IdHTTP1.Get(aURL,tStream);//¿ªÊ¼ÏÂÔØ
try
tStream.Free;
except
end;
end
else
begin
tStream:=TFileStream.Create(aFile,fmCreate);
IdHTTP1.Request.ContentRangeStart:=0;
IdHTTP1.Get(aURL,tStream);//¿ªÊ¼ÏÂÔØ
try
tStream.Free;
except
end;
end;
Except
abort;
end;
end;//ifnotThread1.Terminated
end;

关于线程:

以下代码写在 Uses单元下面。控件TYPE单元上面。

//线程类
type
TThread1 = class(TThread)
// Variable
protected
FMMUrl:string;
FDestPath:string;
FSubJ:string;
procedure Execute;override;
public
// Methods
// Constructor/Destructor
constructor Create();
end;

3、访问和下载都搞定了,现在要解决的是字符串的类型转换问题。

这里可能涉及到的字符串类型是: array of byte ,array of string ,TStringList。
最常用的字符串操作函数:Copy , SetLength, Length , StrLen, Chr , Inc ,Pos。
我在这里收集了一些字符串转换函数,但是有时候不得不自己写一些函数来满足具体的转换要求。
(就不弄成图片啦,方便需要的朋友Ctrl+C)

以上就是最主要的技术点。解决这3个方面的问题了,其他的问题都不难。比如
获取当前系统内的某个盘盘符
读取无类型文件、二进制文件
进度条的设置
等等。

需要注意的地方是:
1、如果申请了一个变量,模板,类实例...注意把它Free,Terminate,Destroy,Delete,或者别的什么。一定要释放。
2、有可能的话,所有的变量全部都要初始化,免得出现莫名其妙的错误。同样的,能手动释放的就释放。
3、如果出了什么问题,一定是代码有问题。不要去怀疑编译器,某人(我!)水平还没达到质疑编译器的程度。

最后,如果碰巧你也在做这方面的任务,而且你又是比我还新的新手~ 欢迎来问我~

//***********************************************************************
//
// 自定义函数/方法
//
//***********************************************************************
//=======================================================================
// Helper Methods
//=======================================================================
function TForm1.GetTempDir(): string;//获取系统临时文件夹
var
Buffer: array[0..1023] of Char;
begin
SetString(Result, Buffer, GetTempPath(SizeOf(Buffer), Buffer));
end;
//=======================================================================
// Helper Methods
//=======================================================================
function TForm1.SplitString(const Source,ch:string):TStringList;// Split() in Delphi
var
temp:String;
i:Integer;
begin
Result:=TStringList.Create;
if Source='' then exit;
temp:=Source;
i:=pos(ch,Source);
while i<>0 do
begin
Result.add(copy(temp,0,i-1));
Delete(temp,1,i+length(ch)-1);
i:=pos(ch,temp);
end;
Result.add(temp);
end;
//=======================================================================
// Helper Methods
//=======================================================================
function TForm1.LastIndexOf(const s,str:String):integer;
var
i: integer;
tmpStr:string;
begin
tmpStr:= s;
i := Pos(str,tmpStr);
while i <>0 do
begin
Delete(tmpStr,1,i);
i := Pos(str,tmpStr);
end;
Result := Pos(tmpStr,s);
end;
//=======================================================================
// Helper Methods
//=======================================================================
function TForm1.StrToByte(GTuserProductSN:string):TByteDynArray;
var
a: TByteDynArray;
begin
SetLength(a, Length(GTuserProductSN));
Move(GTuserProductSN[1], a[0], Length(GTuserProductSN));

Result:= a;
end;
//=======================================================================
// Helper Methods
//=======================================================================
function TForm1.HexCharToInt(ch:char):integer;// 16½øÖƵÄ×Ö·ûת³ÉÏà¶ÔÓ¦µÄÕûÊý
begin
Case ord(ch) of
65:Result:= 10;
66:Result:= 11;
67:Result:= 12;
68:Result:= 13;
69:Result:= 14;
70:Result:= 15;
else
Result:= StrToint(ch);
end;
end;
//=======================================================================
// Helper Methods
//=======================================================================
function TForm1.HexCharToStr(const S:string):string;
var
a:string;
i:integer;
begin
a := '';
i := 1;
while i < length(s) do
begin
a := a + chr(HexCharToInt(s[i])*16 + HexCharToInt(s[i+1]));
i := i + 2;
end;
Result := a;
end;
//=======================================================================
// Helper Methods
//=======================================================================
//获取磁盘空间
function TForm1.GetDiskSpace(const _type,DriverName:String):Cardinal;
var
driver:pchar;
sec1, byt1,TotalSpace, FreeSpace:longword;
begin
driver:= Pchar(DriverName + ':\');//DriverName like : C D E H ,not C: or C:\
GetDiskFreeSpace(driver, sec1, byt1, FreeSpace, TotalSpace);
FreeSpace := FreeSpace * sec1 * byt1;
TotalSpace := TotalSpace * sec1 * byt1;
if _type = 'Free' then
Result:= FreeSpace
else if _type = 'Total' then
Result:= TotalSpace
else
Result:= 0;
end;
//=======================================================================
// Helper Methods
//=======================================================================
function TForm1.DoCopyDir(sDirName:String; sToDirName:String):Boolean;
var
hFindFile: Cardinal;
t,tfile:String;
sCurDir:String[255];
FindFileData:WIN32_FIND_DATA;
begin
sCurDir:=GetCurrentDir;
ChDir(sDirName);
hFindFile:=FindFirstFile('*.*',FindFileData);
if hFindFile<>INVALID_HANDLE_VALUE then
begin
if not DirectoryExists(sToDirName) then
ForceDirectories(sToDirName);
repeat
tfile:=FindFileData.cFileName;
if (tfile='.') or (tfile='..') then
Continue;
if FindFileData.dwFileAttributes=
FILE_ATTRIBUTE_DIRECTORY then
begin
t:=sToDirName+'\'+tfile;
if not DirectoryExists(t) then
ForceDirectories(t);
if sDirName[Length(sDirName)]<>'\' then
DoCopyDir(sDirName+'\'+tfile,t)
else
DoCopyDir(sDirName+tfile,sToDirName+tfile);
end
else
begin
t:=sToDirName+'\'+tFile;
CopyFile(PChar(tfile),PChar(t),False);
end;
until (FindNextFile(hFindFile, FindFileData)=false);
Windows.FindClose(hFindFile);
end
else
begin
ChDir(sCurDir);
result:=false;
exit;
end;
ChDir(sCurDir);
result:=true;
end;

function TForm1.CopyDir(sDirName:String; sToDirName:string):Boolean;
begin
if Length(sDirName)<=0 then
exit;
Result:=DoCopyDir(sDirName,sToDirName);
end;
//=======================================================================
// Helper Methods
//=======================================================================
function TForm1.DeleteDir(sDirName:string):Boolean;
var
sr: TSearchRec;
sPath,sFile: String;
begin
try
if Copy(sDirName,Length(sDirName),1) <> '\' then
sPath := sDirName + '\'
else
sPath := sDirName;
if FindFirst(sPath+'*.*',faAnyFile, sr) = 0 then
begin
repeat
sFile:=Trim(sr.Name);
if sFile='.' then Continue;
if sFile='..' then Continue;
sFile:=sPath+sr.Name;
if (sr.Attr and faDirectory)<>0 then
DeleteDir(sFile)
else if (sr.Attr and faAnyFile) = sr.Attr then
DeleteFile(sFile);
until FindNext(sr) <> 0;
FindClose(sr);
end;
RemoveDir(sPath);
except
Result:= false;
end;
end;

你可能感兴趣的:(多线程,webservice,百度,SOAP,Delphi)