cmdline_page.iss.inc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
  2. SPDX-License-Identifier: Apache-2.0 }
  3. { ------------------------------ Progress & log page for command line tools ------------------------------ }
  4. var
  5. CmdlineInstallCancel: Boolean;
  6. { ------------------------------ Splitting strings into lines and adding them to TStrings ------------------------------ }
  7. procedure StringsAddLine(Dest: TStrings; Line: String; var ReplaceLastLine: Boolean);
  8. begin
  9. if ReplaceLastLine then
  10. begin
  11. Dest.Strings[Dest.Count - 1] := Line;
  12. ReplaceLastLine := False;
  13. end else begin
  14. Dest.Add(Line);
  15. end;
  16. end;
  17. procedure StrSplitAppendToList(Text: String; Dest: TStrings; var LastLine: String);
  18. var
  19. pCR, pLF, Len: Integer;
  20. Tmp: String;
  21. ReplaceLastLine: Boolean;
  22. begin
  23. if Length(LastLine) > 0 then
  24. begin
  25. ReplaceLastLine := True;
  26. Text := LastLine + Text;
  27. end;
  28. repeat
  29. Len := Length(Text);
  30. pLF := Pos(#10, Text);
  31. pCR := Pos(#13, Text);
  32. if (pLF > 0) and ((pCR = 0) or (pLF < pCR) or (pLF = pCR + 1)) then
  33. begin
  34. if pLF < pCR then
  35. Tmp := Copy(Text, 1, pLF - 1)
  36. else
  37. Tmp := Copy(Text, 1, pLF - 2);
  38. StringsAddLine(Dest, Tmp, ReplaceLastLine);
  39. Text := Copy(Text, pLF + 1, Len)
  40. end else begin
  41. if (pCR = Len) or (pCR = 0) then
  42. begin
  43. break;
  44. end;
  45. Text := Copy(Text, pCR + 1, Len)
  46. end;
  47. until (pLF = 0) and (pCR = 0);
  48. LastLine := Text;
  49. if pCR = Len then
  50. begin
  51. Text := Copy(Text, 1, pCR - 1);
  52. end;
  53. if Length(LastLine) > 0 then
  54. begin
  55. StringsAddLine(Dest, Text, ReplaceLastLine);
  56. end;
  57. end;
  58. { ------------------------------ The actual command line install page ------------------------------ }
  59. procedure OnCmdlineInstallCancel(Sender: TObject);
  60. begin
  61. CmdlineInstallCancel := True;
  62. end;
  63. function DoCmdlineInstall(caption, description, command: String): Boolean;
  64. var
  65. CmdlineInstallPage: TOutputProgressWizardPage;
  66. Res: Integer;
  67. Handle: Longword;
  68. ExitCode: Integer;
  69. LogTextAnsi: AnsiString;
  70. LogText, LeftOver: String;
  71. Memo: TNewMemo;
  72. PrevCancelButtonOnClick: TNotifyEvent;
  73. begin
  74. CmdlineInstallPage := CreateOutputProgressPage('', '')
  75. CmdlineInstallPage.Caption := caption;
  76. CmdlineInstallPage.Description := description;
  77. Memo := TNewMemo.Create(CmdlineInstallPage);
  78. Memo.Top := CmdlineInstallPage.ProgressBar.Top + CmdlineInstallPage.ProgressBar.Height + ScaleY(8);
  79. Memo.Width := CmdlineInstallPage.SurfaceWidth;
  80. Memo.Height := ScaleY(120);
  81. Memo.ScrollBars := ssVertical;
  82. Memo.Parent := CmdlineInstallPage.Surface;
  83. Memo.Lines.Clear();
  84. CmdlineInstallPage.Show();
  85. try
  86. WizardForm.CancelButton.Visible := True;
  87. WizardForm.CancelButton.Enabled := True;
  88. PrevCancelButtonOnClick := WizardForm.CancelButton.OnClick;
  89. WizardForm.CancelButton.OnClick := @OnCmdlineInstallCancel;
  90. CmdlineInstallPage.SetProgress(0, 100);
  91. CmdlineInstallPage.ProgressBar.Style := npbstMarquee;
  92. ExitCode := -1;
  93. Memo.Lines.Append('Running command: ' + command);
  94. Handle := ProcStart(command, ExpandConstant('{tmp}'))
  95. if Handle = 0 then
  96. begin
  97. Log('ProcStart failed');
  98. ExitCode := -2;
  99. end;
  100. while (ExitCode = -1) and not CmdlineInstallCancel do
  101. begin
  102. ExitCode := ProcGetExitCode(Handle);
  103. SetLength(LogTextAnsi, 4096);
  104. Res := ProcGetOutput(Handle, LogTextAnsi, 4096)
  105. if Res > 0 then
  106. begin
  107. SetLength(LogTextAnsi, Res);
  108. LogText := LeftOver + String(LogTextAnsi);
  109. StrSplitAppendToList(LogText, Memo.Lines, LeftOver);
  110. end;
  111. CmdlineInstallPage.SetProgress(0, 100);
  112. Sleep(10);
  113. end;
  114. ProcEnd(Handle);
  115. finally
  116. Log('Done, exit code=' + IntToStr(ExitCode));
  117. Log('--------');
  118. Log(Memo.Lines.Text);
  119. Log('--------');
  120. if CmdlineInstallCancel then
  121. begin
  122. MsgBox('Installation has been cancelled.', mbError, MB_OK);
  123. Result := False;
  124. end else if ExitCode <> 0 then
  125. begin
  126. MsgBox('Installation has failed with exit code ' + IntToStr(ExitCode), mbError, MB_OK);
  127. Result := False;
  128. end else begin
  129. Result := True;
  130. end;
  131. CmdlineInstallPage.Hide;
  132. CmdlineInstallPage.Free;
  133. WizardForm.CancelButton.OnClick := PrevCancelButtonOnClick;
  134. end;
  135. if not Result then
  136. RaiseException('Installation has failed at step: ' + caption);
  137. end;