Function Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean; var Target,Source:TFileStream; MyFileSize:integer; begin try Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareExclusive); Target:=TFileStream.Create(TargetFile,fmOpenWrite or fmShareExclusive); try Target.Seek(0,soFromEnd);//往尾部添加資源 Target.CopyFrom(Source,0); MyFileSize:=Source.Size+Sizeof(MyFileSize);//計(jì)算資源大小,并寫入輔程尾部 Target.WriteBuffer(MyFileSize,sizeof(MyFileSize)); finally Target.Free; Source.Free; end; except Result:=False; Exit; end; Result:=True; end; 有了上面的基礎(chǔ),我們應(yīng)該很容易看得懂這個(gè)函數(shù)。其中參數(shù)SourceFile是 要添加的文件,參數(shù)TargetFile是被添加到的目標(biāo)文件。比如說(shuō)把a(bǔ).exe添加到 b.exe里面可以:Cjt_AddtoFile('a.exe',b.exe');如果添加成功就返回True否則 返回假。 根據(jù)上面的函數(shù)我們可以寫出相反的讀出函數(shù): Function Cjt_LoadFromFile(SourceFile,TargetFile :string):Boolean; var Source:TFileStream; Target:TMemoryStream; MyFileSize:integer; begin try Target:=TMemoryStream.Create; Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone); try Source.Seek(-sizeof(MyFileSize),soFromEnd); Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//讀出資源大小 Source.Seek(-MyFileSize,soFromEnd);//定位到資源位置 Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//取出資源 Target.SaveToFile(TargetFile);//存放到文件 finally Target.Free; Source.Free; end; except Result:=false; Exit; end; Result:=true; end; 其中參數(shù)SourceFile是已經(jīng)添加了文件的文件名稱,參數(shù)TargetFile是取出文 件后保存的目標(biāo)文件名。比如說(shuō)Cjt_LoadFromFile('b.exe','a.txt');在b.exe中 取出文件保存為a.txt。如果取出成功就返回True否則返回假。 打開(kāi)Delphi,新建一個(gè)工程,在窗口上放上一個(gè)Edit控件Edit1和兩個(gè)Button: Button1和Button2。Button的Caption屬性分別設(shè)置為“確定”和“取消”。在 Button1的Click事件中寫代碼: var S:string; begin S:=ChangeFileExt(application.ExeName,'.Cjt'); if Edit1.Text='790617' then begin Cjt_LoadFromFile(Application.ExeName,S); {取出文件保存在當(dāng)前路徑下并命名"原文件.Cjt"} Winexec(pchar(S),SW_Show);{運(yùn)行"原文件.Cjt"} Application.Terminate;{退出程序} end else Application.MessageBox('密碼不對(duì),請(qǐng)重新輸入!','密碼錯(cuò)誤',MB_ICONERROR+MB_OK); 編譯這個(gè)程序,并把EXE文件改名為head.exe。新建一個(gè)文本文件head.rc, 內(nèi)容為: head exefile head.exe,然后把它們拷貝到Delphi的BIN目錄下,執(zhí)行 Dos命令Brcc32.exe head.rc,將產(chǎn)生一個(gè)head.res的文件,這個(gè)文件就是我們要 的資源文件,先留著。 我們的頭文件已經(jīng)建立了,下面我們來(lái)建立添加程序。 新建一個(gè)工程,放上以下控件:一個(gè)Edit,一個(gè)Opendialog,兩個(gè)Button1的 Caption屬性分別設(shè)置為"選擇文件"和"加密"。 在源程序中添加一句:{$R head.res}并把head.res文件拷貝到程序當(dāng)前目錄下。 這樣一來(lái)就把剛才的head.exe跟程序一起編譯了。 在Button1的Cilck事件里面寫下代碼: if OpenDialog1.Execute then Edit1.Text:=OpenDialog1.FileName; 在Button2的Cilck事件里面寫下代碼: var S:String; begin S:=ExtractFilePath(Edit1.Text); if ExtractRes('exefile','head',S+'head.exe') then if Cjt_AddtoFile(Edit1.Text,S+'head.exe') then if DeleteFile(Edit1.Text) then if RenameFile(S+'head.exe',Edit1.Text) then Application.MessageBox('文件加密成功!','信息',MB_ICONINFORMATION+MB_OK) else begin if FileExists(S+'head.exe') then DeleteFile(S+'head.exe'); Application.MessageBox('文件加密失敗!','信息',MB_ICONINFORMATION+MB_OK) end; end; 其中ExtractRes為自定義函數(shù),它的作用是把head.exe從資源文件中取出來(lái)。 Function ExtractRes(ResType, ResName, ResNewName : String):boolean; var Res : TResourceStream; begin try Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType)); try Res.SavetoFile(ResNewName); Result:=true; finally Res.Free; end; except Result:=false; end; end; 注意:我們上面的函數(shù)只不過(guò)是簡(jiǎn)單的把一個(gè)文件添加到另一個(gè)文件的尾部。 實(shí)際應(yīng)用中可以改成可以添加多個(gè)文件,只要根據(jù)實(shí)際大小和個(gè)數(shù)定義好偏移 地址就可以了。比如說(shuō)文件捆綁機(jī)就是把兩個(gè)或者多個(gè)程序添加到一個(gè)頭文件 里面。那些自解壓程序和安裝程序的原理也是一樣的,不過(guò)多了壓縮而已。 比如說(shuō)我們可以引用一個(gè)LAH單元,把流壓縮后再添加,這樣文件就會(huì)變的很小。 讀出來(lái)時(shí)先解壓就可以了。 另外,文中EXE加密器的例子還有很多不完善的地方,比如說(shuō)密碼固定為 "790617",取出EXE運(yùn)行后應(yīng)該等它運(yùn)行完畢后刪除等等,讀者可以自行修改。