2013-05-02 4 views
3

Как я могу получить прогресс, когда выполняю скрипт inno из компилятора командной строки (iscc.exe)?Выполнение командной строки Inno setup

Я могу конвейер вывести выход, но я хочу получить% завершена также.

+3

Если вы собираетесь сделать свой собственный пользовательский интерфейс InnoSetup компилятора, лучше использовать 'библиотеку ISCmplr'. Исходя из быстрого обзора источника, я боюсь, что вам нужно будет создать собственную версию «ISCC», которая будет распечатывать информацию о ходе работы. – TLama

+0

@TLama Спасибо за информацию. Я пытаюсь отобразить прогресс из приложения delphi, поэтому я думаю, что лучшим способом было бы вызвать IsCmplr.dll непосредственно из приложения и перенаправить его обратный вызов на индикатор выполнения приложения. Как и Compil32. – JustMe

+1

Это лучшее, что вы можете сделать. И, пожалуйста! :-) – TLama

ответ

6

Используйте вместо ISCmplr библиотеки. Для вдохновения очень простой компилятор Delphi InnoSetup может выглядеть так (конечно, без жестко заданных путей). Он использует оригинальный CompInt.pas блок из InnoSetup источника пакета:

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, ComCtrls, CompInt; 

const 
    CompLib = ISCmplrDLL; 
    CompPath = 'c:\Program Files (x86)\Inno Setup 5\'; 
    CompScriptProc = {$IFNDEF UNICODE}'ISDllCompileScript'{$ELSE}'ISDllCompileScriptW'{$ENDIF}; 

type 
    TCompScriptProc = function(const Params: TCompileScriptParamsEx): Integer; stdcall; 

    PAppData = ^TAppData; 
    TAppData = record 
    Lines: TStringList; 
    LineNumber: Integer; 
    StatusLabel: TLabel; 
    ProgressBar: TProgressBar; 
    end; 

type 
    TForm1 = class(TForm) 
    Label1: TLabel; 
    Button1: TButton; 
    ProgressBar1: TProgressBar; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    private 
    FCompLibHandle: HMODULE; 
    FCompScriptProc: TCompScriptProc; 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    FCompLibHandle := SafeLoadLibrary(CompPath + CompLib); 
    if FCompLibHandle <> 0 then 
    FCompScriptProc := GetProcAddress(FCompLibHandle, CompScriptProc); 
end; 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
    if FCompLibHandle <> 0 then 
    FreeLibrary(FCompLibHandle); 
end; 

function CompilerCallbackProc(Code: Integer; var Data: TCompilerCallbackData; 
    AppData: Longint): Integer; stdcall; 
begin 
// in every stage you can cancel the compilation if you pass e.g. a Boolean 
// field through the AppData by using the following line: 
// Result := iscrRequestAbort; 

    Result := iscrSuccess; 
    case Code of 
    iscbReadScript: 
    with PAppData(AppData)^ do 
    begin 
     if Data.Reset then 
     LineNumber := 0; 
     if LineNumber < Lines.Count then 
     begin 
     Data.LineRead := PChar(Lines[LineNumber]); 
     Inc(LineNumber); 
     end; 
    end; 
    iscbNotifyStatus: 
     Form1.Label1.Caption := Data.StatusMsg; 
    iscbNotifyIdle: 
    begin 
     with PAppData(AppData)^ do 
     begin 
     ProgressBar.Max := Data.CompressProgressMax; 
     ProgressBar.Position := Data.CompressProgress; 
     StatusLabel.Caption := Format('Bitrate: %d B/s; Remaining time: %d s', 
      [Data.BytesCompressedPerSecond, Data.SecondsRemaining]); 
     Application.ProcessMessages; 
     end; 
    end; 
    iscbNotifySuccess: 
     ShowMessageFmt('Yipee! Compilation succeeded; Output: %s', [Data.OutputExeFilename]); 
    iscbNotifyError: 
     ShowMessageFmt('An error occured! File: %s; Line: %d; Message: %s', [Data.ErrorFilename, 
     Data.ErrorLine, Data.ErrorMsg]); 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    CustData: TAppData; 
    CompParams: TCompileScriptParamsEx; 
begin 
    if Assigned(FCompScriptProc) then 
    begin 
    CustData.Lines := TStringList.Create; 
    try 
     CustData.Lines.LoadFromFile('c:\Program Files (x86)\Inno Setup 5\Examples\Example1.iss'); 
     CustData.LineNumber := 0; 
     CustData.StatusLabel := Label1; 
     CustData.ProgressBar := ProgressBar1; 

     CompParams.Size := SizeOf(CompParams); 
     CompParams.CompilerPath := CompPath;             // path to the folder containing *.e32 files (InnoSetup install folder) 
     CompParams.SourcePath := 'c:\Program Files (x86)\Inno Setup 5\Examples\';    // path to the script file to be compiled 
     CompParams.CallbackProc := CompilerCallbackProc;          // callback procedure which the compiler calls to read the script and for status notifications 
     Pointer(CompParams.AppData) := @CustData;            // custom data passed to the callback procedure 
     CompParams.Options := '';                // additional options; see CompInt.pas for description 

     if FCompScriptProc(CompParams) <> isceNoError then 
     ShowMessage('Compiler Error'); 
    finally 
     CustData.Lines.Free; 
    end; 
    end; 
end; 

end. 
Смежные вопросы