⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xinstall.dpr

📁 文件和并及自释放工具支持释放前中断所设置的进程及释放后启动相应设置的程序
💻 DPR
字号:
program Xinstall;

uses
  Windows,
  SysUtils,
  Classes,
  inifiles,
  //TLHelp32,
  //Registry,
  //shellAPI,
  Tkillprocess in 'Tkillprocess.pas';

{$R *.res}
type
  Tinistruct = class (Tobject)
  private
  public
    inifile:Tinifile;
    beforeKill:array[1..255] of string;
    beforeKillcount:integer;
    beforeRun:array[1..255] of string;
    beforeRunCount:integer;
    afterRun:array[1..255] of string;
    afterRuncount:integer;
    filesName:array[1..255] of string;
    filessize:array[1..255] of longword;
    selfsize:longword;
    filescount:integer;
    filesbase:string;
    constructor Create(inifileName:string);
    destructor Destroy;override;
    procedure writeInifile;
    procedure readInifile;
    function filterPath(str:string):string;
end;
constructor Tinistruct.Create(iniFileName:string);
begin
    inherited Create;
    inifile:=Tinifile.Create(iniFileName);
end;

destructor Tinistruct.Destroy;
begin
    inherited Destroy;
    inifile.Destroy;
end;

procedure Tinistruct.writeInifile;
var i:integer;
begin
    inifile.WriteInteger('files','count',filescount);
    inifile.WriteInteger('files','selfsize',selfsize);
    i:=1;
    while i<=filescount do
    begin
        //inifile.WriteString('files','file'+inttostr(i),filesName[i]);
        inifile.WriteInteger('files','filesize'+inttostr(i),filesSize[i]);
        inc(i);
    end;
    {i:=1;
    inifile.WriteInteger('before run','count',beforeRunCount);
    while i<=beforeRunCount do
    begin
        inifile.WriteString('before run','run'+inttostr(i),beforeRun[i]);
        inc(i);
    end;
    i:=1;
    inifile.WriteInteger('after run','count',afterRunCount);
    while i<=afterRunCount do
    begin
        inifile.WriteString('after run','run'+inttostr(i),afterRun[i]);
        inc(i);
    end;
    i:=1;
    inifile.WriteInteger('before kill','count',beforeKillCount);
    while i<=beforeKillCount do
    begin
        inifile.WriteString('before kill','process'+inttostr(i),beforeKill[i]);
        inc(i);
    end;}
    inifile.UpdateFile;
end;

procedure Tinistruct.readInifile;
var i:integer;
begin
    i:=1;
    filesbase:=filterPath(inifile.ReadString('files','filesbase','./'));
    filescount:=inifile.ReadInteger('files','count',0);
    selfsize:=inifile.ReadInteger('files','selfsize',0);
    while i<=filescount do
    begin
        filesName[i]:=inifile.ReadString('files','file'+inttostr(i),'');
        filesSize[i]:=inifile.ReadInteger('files','filesize'+inttostr(i),0);
        inc(i);
    end;
    i:=1;
    beforeRunCount:=inifile.ReadInteger('before run','count',0);
    while i<=beforeRunCount do
    begin
        beforeRun[i]:=filterPath(inifile.ReadString('before run','run'+inttostr(i),''));
        inc(i);
    end;
    i:=1;
    afterRunCount:=inifile.ReadInteger('after run','count',0);
    while i<=afterRunCount do
    begin
        afterRun[i]:=filterPath(inifile.ReadString('after run','run'+inttostr(i),''));
        inc(i);
    end;
    i:=1;
    beforekillcount:=inifile.ReadInteger('before kill','count',0);
    while i<=beforekillcount do
    begin
        beforekill[i]:=inifile.ReadString('before kill','process'+inttostr(i),'');
        inc(i);
    end;
    inifile.UpdateFile;
end;
function Tinistruct.filterPath(str:string):string;
var
    windir:array [0..128] of char;
    systemdisk:array [0..2] of char;
begin
    getwindowsDirectory(windir,128);
    strplcopy(systemdisk, windir, 2);
    str:=StringReplace(str, '%SYSTEMDISK%', systemdisk, [rfReplaceAll]);
    result:=StringReplace(str, '\\', '\', [rfReplaceAll]);
end;

type
  Txinstall = class (Tobject)

  private
    paramct:integer;
    { Private declarations }
  public
    inistruct:Tinistruct;
    Totalstream:Tmemorystream;
    selffile:Tmemorystream;
    selfsize:longword;
    selfname:string;
    filesname:array[1..256] of string;
    files:array[1..256] of Tmemorystream;
    filessize:array[1..256] of Longword;
    constructor CreateWithIniFile(iniFileName:string);
    constructor CreateWithLoadFiles(paramstrs:Tstrings);
    constructor CreateBlockFiles(iniFileName:string);
    destructor Destroy;override;
    procedure releaseIniFile(iniFileName:string);
    procedure BlockFileStream;
    procedure SaveFiles;
    function Totalsize:Longword;
    procedure setStream(appsize:longword);
    procedure AppendStream(streamRES:Tmemorystream;streamDES:Tmemorystream);
    procedure AppendFilesStream;
    function BlockStream(StreamRES:Tmemorystream;StreamDES:Tmemorystream;Count:Longword):TmemoryStream;
    procedure setIniStruct;
    procedure getInistruct;
    procedure setFilesBase(str:string);
    procedure AddBeforeKill(str:string);
    procedure AddbeforeRun(str:string);
    procedure AddAfterRun(str:string);
    procedure AddFile(filename:string);
    procedure beforekill;
    procedure beforeRun;
    procedure afterRun;
    { Public declarations }
end;
constructor Txinstall.CreateWithIniFile(InifileName:string);
var
    i,h:integer;
begin
    inherited Create;
    inistruct:=Tinistruct.create(InifileName);
    inistruct.readInifile;
    selfname:=paramstr(0);
    selffile:=TmemoryStream.Create;
    selffile.LoadFromFile(selfname);
    selfsize:=selffile.Size;
    paramct:=inistruct.filescount;
    i:=1;
    h:=1;
    while i<=paramct do
    begin
        if fileexists(inistruct.filesName[i]) then
        begin
            filesname[h]:='./'+inistruct.filesName[i];
            files[h]:=Tmemorystream.Create;
            files[h].LoadFromFile(filesname[h]);
            filessize[h]:=files[h].Size;
            inc(h);
        end;
        inc(i);
    end;
    paramct:=h-1;
    setinistruct;
    inistruct.writeInifile;
end;
constructor Txinstall.CreateWithLoadFiles(paramstrs:Tstrings);
var
    h:integer;
begin
    inherited Create;
    h:=1;
    selffile:=TmemoryStream.Create;
    inistruct:=Tinistruct.create('./xinstall.ini');
    selfname:=paramstrs.Strings[0];
    selffile.LoadFromFile(selfname);
    selfsize:=selffile.Size;
    paramct:=paramstrs.Count-1;
    while h<=paramct do
    begin
       files[h]:=TmemoryStream.Create;
       filesname[h]:=paramstrs.Strings[h];
       files[h].LoadFromFile(filesname[h]);
       filesSize[h] := files[h].Size;
       inc(h);
    end;
    setinistruct;
    inistruct.writeInifile;
end;

constructor Txinstall.CreateBlockFiles(iniFileName:string);
begin    inherited Create;
    releaseIniFile(iniFileName);
    inistruct:=Tinistruct.Create(iniFileName);
    inistruct.readInifile;
    getinistruct;
end;

procedure Txinstall.releaseIniFile(iniFileName:string);
var
    psplit:pchar;
    sizeOfStr:string;
    sizeOfInt:integer;
    inifilestream:tmemorystream;
begin
    getmem(psplit,4);
    totalstream:=Tmemorystream.Create;
    totalstream.LoadFromFile(paramstr(0));
    totalstream.Position:=totalstream.Size-4;
    totalstream.readBuffer(psplit^,4);
    sizeOfstr:=strpas(psplit);
    sizeofint:=strtoint(sizeOfstr)+4;
    freemem(psplit);
    totalstream.Position:=totalstream.Size-sizeOfint;
    inifilestream:=Tmemorystream.Create;
    inifilestream.SetSize(sizeofint-4);
    inifilestream.Position:=0;
    BlockStream(totalstream,inifilestream,sizeofint-4);
    inifilestream.SaveToFile(iniFileName);
    inifilestream.Destroy;
    {release ini}
end;

procedure Txinstall.BlockFileStream;
var i:integer;
begin
    i:=1;
    totalstream.Position:=selfsize;
    while i<paramct do
    begin
        files[i].SetSize(filessize[i]);
        files[i]:=BlockStream(totalstream,files[i],filessize[i]);
        inc(i);
    end;
end;
function Txinstall.BlockStream(StreamRES:Tmemorystream;StreamDES:Tmemorystream;Count:Longword):Tmemorystream;
begin
    StreamDES.Position:=0;
    StreamDES.SetSize(Count);
    if Count <> 0 then StreamDES.writeBuffer(Pointer(Longint(streamRES.Memory) + StreamRES.Position)^, Count);
    totalstream.Position:=totalstream.Position+count;
    result:=StreamDES;
end;


procedure Txinstall.SaveFiles;
var i:integer;
begin
    i:=1;
    while i<paramct do
    begin
        if not DirectoryExists(inistruct.filesbase) then  mkdir(inistruct.filesbase);
        files[i].SaveToFile(inistruct.filesbase+'\'+filesname[i]);
        inc(i);
    end;
end;

procedure Txinstall.AddFile(filename:string);
begin
    inc(paramct);
    files[paramct]:=Tmemorystream.Create;
    filesname[paramct]:=filename;
    files[paramct].LoadFromfile(filesname[paramct]);
    filesSize[paramct]:=files[paramct].Size;
    setinistruct;
    setstream(0);
end;

destructor Txinstall.Destroy;
var i:integer;
begin
    i:=1;
    while i<=paramct do
    begin
        files[i].Destroy;
        inc(i);
    end;
    selffile.Destroy;
    totalstream.Destroy;
    inistruct.Destroy;
    inherited Destroy;
end;

procedure Txinstall.setFilesBase(str:string);
begin
    inistruct.filesbase:=inistruct.filterPath(str);
end;

procedure Txinstall.AddBeforeKill(str:string);
begin
    inc(inistruct.beforeKillcount);
    inistruct.BeforeKill[inistruct.BeforeKillCount]:=str;
end;

procedure Txinstall.AddbeforeRun(str:string);
begin
    inc(inistruct.beforeRunCount);
    inistruct.beforeRun[inistruct.beforeRunCount]:=str;
end;

procedure Txinstall.AddAfterRun(str:string);
begin
    inc(inistruct.beforeRunCount);
    inistruct.afterRun[inistruct.beforeRunCount]:=str;
end;

function Txinstall.Totalsize:longword;
var
    i:longword;
    h:integer;
begin
    i:=0;
    h:=0;
    while h<=paramct do
    begin
        i:=i+filessize[h+1];
        inc(h);
    end;
    result:=i+selfsize;
end;

procedure Txinstall.setStream(appsize:longword);
begin
    totalstream:=Tmemorystream.Create;
    totalstream.SetSize(totalsize+appsize);
    totalstream.Position:=0;
    totalstream.Clear;
end;

procedure Txinstall.AppendStream(streamRES:Tmemorystream;streamDES:Tmemorystream);
var
  Count: Longint;
begin
  streamRES.Position:=StreamRES.size;
  Count := StreamRES.Size+StreamDES.Size;
  StreamRES.setsize(count);
  if Count <> 0 then StreamDES.ReadBuffer(Pointer(Longint(streamRES.Memory) + StreamRES.Position)^, StreamDES.size);
//  showmessage('StreamRES = '+inttostr(StreamRES.Position)+#13+'StreamDES = '+inttostr(streamDES.Position));
end;

procedure Txinstall.setIniStruct;
var i:integer;
begin
    i:=1;
    inistruct.selfsize:=selfsize;
    inistruct.filescount:=paramct;
    while i<=inistruct.filescount do
    begin
        inistruct.filesName[i]:=filesname[i];
        inistruct.filessize[i]:=filessize[i];
        inc(i);
    end;
end;

procedure Txinstall.getInistruct;
var
    i:integer;
begin
    i:=1;
    selffile:=Tmemorystream.Create;
    selfsize:=inistruct.selfsize;
    paramct:=inistruct.filescount;
    while i<=paramct do
    begin
        files[i]:=Tmemorystream.Create;
        filesname[i]:=inistruct.filesName[i];
        filessize[i]:=inistruct.filesSize[i];
        inc(i);
    end;
end;

procedure Txinstall.AppendFilesStream;
var i:integer;
    splitstream:TmemoryStream;
    psplit:pchar;
    SizeOfStr:string;
    SizeOfint:integer;
begin
  setstream(4);
  Appendstream(Totalstream,selffile);
  i:=1;
  while i<paramct do
  begin
    appendstream(Totalstream,files[i]);
    inc(i);
  end;
  splitstream:=TmemoryStream.Create;
  getmem(psplit,4);
  SizeOfInt:=strlen(pchar(inttostr(filessize[i])));
  SizeOfStr:=inttostr(filessize[i]);
  if SizeOfInt<4 then
    while (4-SizeOfint)>0 do
    begin
        SizeofStr:='0'+SizeOfStr;
        inc(SizeOfint);
    end;
  strcopy(psplit,pchar(sizeofstr));
  splitstream.SetSize(4);
  splitstream.WriteBuffer(psplit^,4);
  freemem(psplit);
  //splitstream.SaveToFile('split.txt');
  appendstream(Totalstream,files[i]);
  splitstream.position:=0;
  appendstream(totalstream,splitstream);
  inistruct.writeInifile;
  splitstream.Destroy;
end;

procedure Txinstall.beforekill;
var
    kp:killprocess;
    i:integer;
begin
    kp:=killprocess.create;
    i:=1;
    while i<=inistruct.beforeKillcount do
    begin
        kp.killprocess(inistruct.beforekill[i]);
        inc(i);
    end;
    kp.Destroy;
end;

procedure Txinstall.beforeRun;
var
    i:integer;
begin
    i:=1;
    while i<=inistruct.beforeRunCount do
    begin
        winexec(pchar(inistruct.beforeRun[1]),SW_SHOW);
        inc(i);
    end;
end;

procedure Txinstall.afterRun;
var
    i:integer;
begin
    i:=1;
    while i<=inistruct.afterRunCount do
    begin
        winexec(pchar(inistruct.afterRun[i]),SW_SHOW);
        inc(i);
    end;
end;

var
    xinst:Txinstall;
    //outfile:tmemorystream;
    //i:integer;
    //paramstrs:tstrings;
    //inifile:Tinifile;
begin
  xinst:=Txinstall.Create;
  if paramcount>0 then
  begin
     if paramstr(1)='xinstall.ini' then
     begin
        xinst:=Txinstall.CreateWithIniFile('./xinstall.ini');
        xinst.AppendFilesStream;
        xinst.Totalstream.SaveTofile('./setup.exe');
     end
     else
     begin
        xinst:=Txinstall.CreateBlockFiles(paramstr(1));
        xinst.beforekill;
        xinst.beforeRun;
        xinst.BlockFileStream;
        xinst.SaveFiles;
        xinst.afterRun;
        deletefile(paramstr(1));
     end
  end
  else  //paramcount=0
  begin
     xinst:=Txinstall.CreateBlockFiles('./xinstall.ini');
     xinst.beforekill;
     xinst.beforeRun;
     xinst.BlockFileStream;
     xinst.SaveFiles;
     xinst.afterRun;
     deletefile('./xinstall.ini');
  end;
  xinst.Destroy;
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -