2017-01-29 6 views
1

私は現在Inno Download Pluginを使用してインストーラのファイルをダウンロードしていますが、これはファイルを正しくダウンロードできないという最大の問題です。接続不良のような多くの理由のために。私はファイルをダウンロードする別の方法を追加したいので、ユーザーは通常の方法、またはトレントの方法を選択するかもしれません。私はaria2c.exeアプリケーション(https://aria2.github.io/)を使用できることを知っています。誰かがinno setupのコードに実装するのを手伝ってくれますか?Inno Setup torrentダウンロードの実装

私が必要とするのは、torrent(aria2.exe)を使用して7zファイルをダウンロードし、そのコンテンツを{{app}}の場所にある定義されたフォルダに解凍することです。

おそらく、私が必要とするのは良いコード例です。

答えて

1

aria2cを実行して出力をファイルにリダイレクトし、ダウンロードの進行状況を確認するためにファイルの内容をポーリングします。

それは実際にこの答えのための私のソリューションと非常に似ています:
Inno Setup - Make Inno Setup Installer report its installation progress status to master installer


#define TorrentMagnet "magnet:..." 

[Files] 
Source: aria2c.exe; Flags: dontcopy 
Source: InnoCallback.dll; Flags: dontcopy 

[Code] 

function BufferToAnsi(const Buffer: string): AnsiString; 
var 
    W: Word; 
    I: Integer; 
begin 
    SetLength(Result, Length(Buffer) * 2); 
    for I := 1 to Length(Buffer) do 
    begin 
    W := Ord(Buffer[I]); 
    Result[(I * 2)] := Chr(W shr 8); { high byte } 
    Result[(I * 2) - 1] := Chr(Byte(W)); { low byte } 
    end; 
end; 

type 
    TTimerProc = procedure(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord); 

function SetTimer(Wnd: LongWord; IDEvent, Elapse: LongWord; TimerFunc: LongWord): LongWord; 
    external '[email protected] stdcall'; 
function KillTimer(hWnd: LongWord; uIDEvent: LongWord): BOOL; 
    external '[email protected] stdcall'; 

function WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord; 
    external '[email protected]:innocallback.dll stdcall'; 

var 
    ProgressPage: TOutputProgressWizardPage; 
    ProgressFileName: string; 

procedure UpdateProgressProc(H: LongWord; Msg: LongWord; Event: LongWord; Time: LongWord); 
var 
    S: AnsiString; 
    I: Integer; 
    L: Integer; 
    P: Integer; 
    Max: Integer; 
    Progress: string; 
    Buffer: string; 
    Stream: TFileStream; 
    Transferred: string; 
    Percent: Integer; 
    Found: Boolean; 
begin 
    Found := False; 
    try 
    { Need shared read as the output file is locked for writting, } 
    { so we cannot use LoadStringFromFile } 
    Stream := TFileStream.Create(ProgressFileName, fmOpenRead or fmShareDenyNone); 
    try 
     L := Stream.Size; 
     Max := 100*2014; 
     if L > Max then 
     begin 
     Stream.Position := L - Max; 
     L := Max; 
     end; 
     SetLength(Buffer, (L div 2) + (L mod 2)); 
     Stream.ReadBuffer(Buffer, L); 
     S := BufferToAnsi(Buffer); 
    finally 
     Stream.Free; 
    end; 

    if S = '' then 
    begin 
     Log(Format('Progress file %s is empty', [ProgressFileName])); 
    end; 
    except 
    Log(Format('Failed to read progress from file %s', [ProgressFileName])); 
    end; 

    if S <> '' then 
    begin 
    P := Pos('[#', S); 
    if P = 0 then 
    begin 
     Log('Not found any progress line'); 
    end 
     else 
    begin 
     repeat 
     Delete(S, 1, P - 1); 
     P := Pos(']', S); 
     Progress := Copy(S, 2, P - 2); 
     Delete(S, 1, P); 
     P := Pos('[#', S); 
     until (P = 0); 

     Log(Format('Found progress line: %s', [Progress])); 
     P := Pos(' ', Progress); 
     if P > 0 then 
     begin 
     Log('A'); 
     Delete(Progress, 1, P); 
     P := Pos('(', Progress); 
     if P > 0 then 
     begin 
      Log('b'); 
      Transferred := Copy(Progress, 1, P - 1); 
      Delete(Progress, 1, P); 
      P := Pos('%)', Progress); 
      if P > 0 then 
      begin 
      Log('c'); 
      Percent := StrToIntDef(Copy(Progress, 1, P - 1), -1); 
      if Percent >= 0 then 
      begin 
       Log(Format('Transferred: %s, Percent: %d', [Transferred, Percent])); 
       ProgressPage.SetProgress(Percent, 100); 
       ProgressPage.SetText(Format('Transferred: %s', [Transferred]), ''); 
       Found := True; 
      end; 
      end;  
     end; 
     end; 
    end; 
    end; 

    if not Found then 
    begin 
    Log('No new data found'); 
    { no new progress data, at least pump the message queue } 
    ProgressPage.SetProgress(ProgressPage.ProgressBar.Position, 100); 
    end; 
end; 

function PrepareToInstall(var NeedsRestart: Boolean): String; 
var 
    TorrentDownloaderPath: string; 
    TempPath: string; 
    CommandLine: string; 
    Timer: LongWord; 
    InstallError: string; 
    ResultCode: Integer; 
    S: AnsiString; 
begin 
    ExtractTemporaryFile('aria2c.exe'); 

    ProgressPage := CreateOutputProgressPage('Torrent download', 'Downloading torrent...'); 
    ProgressPage.SetProgress(0, 100); 
    ProgressPage.Show; 
    try 
    Timer := SetTimer(0, 0, 250, WrapTimerProc(@UpdateProgressProc, 4)); 

    TempPath := ExpandConstant('{tmp}'); 
    TorrentDownloaderPath := TempPath + '\aria2c.exe'; 
    ProgressFileName := ExpandConstant('{tmp}\progress.txt'); 
    Log(Format('Expecting progress in %s', [ProgressFileName])); 
    CommandLine := 
     Format('"%s" "%s" > "%s"', [ 
     TorrentDownloaderPath, '{#TorrentMagnet}', ProgressFileName]); 
    Log(Format('Executing: %s', [CommandLine])); 
    CommandLine := Format('/C "%s"', [CommandLine]); 
    if not Exec(ExpandConstant('{cmd}'), CommandLine, TempPath, SW_HIDE, 
       ewWaitUntilTerminated, ResultCode) then 
    begin 
     Result := 'Cannot start torrent download'; 
    end 
     else 
    if ResultCode <> 0 then 
    begin 
     LoadStringFromFile(ProgressFileName, S); 
     Result := Format('Torrent download failed with code %d', [ResultCode]); 
     Log(Result); 
     Log('Output: ' + S); 
    end; 
    finally 
    { Clean up } 
    KillTimer(0, Timer); 
    ProgressPage.Hide; 
    DeleteFile(ProgressFileName); 
    end; 
end; 

BufferToAnsi及びその使用はに基づいています。
Inno Setup LoadStringFromFile fails when file is open in another process


Torrent download progress

+0

私の回答は役に立ちましたか? –