Advertisement
Guest User

Untitled

a guest
Jan 3rd, 2018
375
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.32 KB | None | 0 0
  1. #define MyAppName "NAME"
  2. #define MyAppVersion "Repack"
  3. #define MyAppPublisher "PUBLISHER"
  4. #define MyAppExeName "EXECUTABLE.exe"
  5.  
  6. [Setup]
  7. AppName={#MyAppName}
  8. AppVerName={#MyAppVersion}
  9. AppPublisher={#MyAppPublisher}
  10. DefaultDirName={pf}\{#MyAppPublisher}\{#MyAppName}
  11. DefaultGroupName={#MyAppPublisher}\{#MyAppName}
  12. AllowNoIcons=yes
  13. OutputBaseFilename=install
  14. OutputDir=C:\Users\K\Desktop
  15. WizardImageFile=C:\Users\K\Desktop\NORMAL.bmp
  16. WizardSmallImageFile=C:\Users\K\Desktop\SMALL.bmp
  17. SetupIconFile=C:\Users\K\Desktop\Icon.ico
  18.  
  19. [Tasks]
  20. Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
  21. Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
  22.  
  23. [Icons]
  24. Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
  25. Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
  26. Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
  27. Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon
  28.  
  29. [Run]
  30. Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
  31.  
  32. [Languages]
  33. Name: eng; MessagesFile: compiler:default.isl
  34. ;Name: spanish; MessagesFile: compiler:Languages\spanish.isl
  35. ;Name: brazilianportuguese; MessagesFile: compiler:Languages\brazilianportuguese.isl
  36.  
  37. [CustomMessages]
  38. eng.ArcBreak=Installation cancelled!
  39. eng.ArcError=Decompression failed with error code %1
  40. eng.ArcBroken=Archive %1 is damaged%nor not enough free space.
  41. eng.ArcFail=Decompression failed!
  42. eng.ArcTitle=Extracting FreeArc archive...
  43. eng.ArcInfo=Archive: %1 of %2
  44. eng.ArcInfoExt=Archive: %1 из %2, size %3 of %5, %4%% processed
  45. eng.ArcFinish=Unpacked archives: %1, received files: %2 [%3]
  46. eng.StatusInfo=Files: %1%2, progress %3%%, remaining time %4
  47. eng.AllProgress=Overall extraction progress: %1%%
  48. eng.Extracting=Extracting: %1
  49. eng.ExtractedInfo=Extracted %1 Mb of %2 Mb
  50. eng.taskbar=%1%%, %2 remains
  51. eng.remains=Remaining time: %1
  52. eng.LongTime=at no time
  53. eng.ending=ending
  54. eng.hour= hours
  55. eng.min= mins
  56. eng.sec= secs
  57.  
  58. [Files]
  59. Source: .\data-1.bin; DestDir: {app}\{#MyAppPublisher}\{#MyAppName}; Flags: nocompression
  60. Source: unarc.dll; DestDir: {tmp}; Flags: dontcopy deleteafterinstall
  61. Source: compiler:InnoCallback.dll; DestDir: {tmp}; Flags: dontcopy
  62.  
  63. [UninstallDelete]
  64. Type: filesandordirs; Name: {app}
  65.  
  66. [Code]
  67. const
  68. Archives = '{src}\data-1.bin'; // укажите расположение архивов FreeArc; для внешних файлов строку в [Files] добавлять необязательно
  69.  
  70. PM_REMOVE = 1;
  71. CP_ACP = 0; CP_UTF8 = 65001;
  72. oneMb = 1048576;
  73.  
  74. type
  75. #ifdef UNICODE ; если у вас ошибка на этой строке, то установите препроцессор или исправьте скрипт для вашей версии Inno Setup
  76. #define A "W"
  77. #else
  78. #define A "A" ; точка входа в SetWindowText, {#A} меняется на A или W в зависимости от версии
  79. #endif
  80. #if Ver < 84018176
  81. AnsiString = String; // There is no need for this line in Inno Setup 5.2.4 and above (для Inno Setup версий 5.2.4 и выше эта строка не нужна)
  82. #endif
  83.  
  84. TMyMsg = record
  85. hwnd: HWND;
  86. message: UINT;
  87. wParam: Longint;
  88. lParam: Longint;
  89. time: DWORD;
  90. pt: TPoint;
  91. end;
  92.  
  93. TFreeArcCallback = function (what: PAnsiChar; int1, int2: Integer; str: PAnsiChar): Integer;
  94. TArc = record Path: string; OrigSize: Integer; Size: Extended; end;
  95.  
  96. var
  97. ExtractFile: TLabel;
  98. lblExtractFileName: TLabel;
  99. btnCancelUnpacking: TButton;
  100. CancelCode, n, UnPackError, StartInstall: Integer;
  101. Arcs: array of TArc;
  102. msgError: string;
  103. lastMb: Integer;
  104. baseMb: Integer;
  105. totalUncompressedSize: Integer; // total uncompressed size of archive data in mb
  106. LastTimerEvent: DWORD;
  107.  
  108. Function MultiByteToWideChar(CodePage: UINT; dwFlags: DWORD; lpMultiByteStr: string; cbMultiByte: integer; lpWideCharStr: string; cchWideChar: integer): longint; external 'MultiByteToWideChar@kernel32.dll stdcall';
  109. Function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD; lpWideCharStr: string; cchWideChar: integer; lpMultiByteStr: string; cbMultiByte: integer; lpDefaultChar: integer; lpUsedDefaultChar: integer): longint; external 'WideCharToMultiByte@kernel32.dll stdcall';
  110.  
  111. function PeekMessage(var lpMsg: TMyMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; external 'PeekMessageA@user32.dll stdcall';
  112. function TranslateMessage(const lpMsg: TMyMsg): BOOL; external 'TranslateMessage@user32.dll stdcall';
  113. function DispatchMessage(const lpMsg: TMyMsg): Longint; external 'DispatchMessageA@user32.dll stdcall';
  114.  
  115. Function OemToChar(lpszSrc, lpszDst: AnsiString): longint; external 'OemToCharA@user32.dll stdcall';
  116. function GetWindowLong(hWnd, nIndex: Integer): Longint; external 'GetWindowLongA@user32 stdcall delayload';
  117. function SetWindowText(hWnd: Longint; lpString: String): Longint; external 'SetWindowText{#A}@user32 stdcall delayload';
  118.  
  119. function GetTickCount: DWord; external 'GetTickCount@kernel32';
  120. function WrapFreeArcCallback (callback: TFreeArcCallback; paramcount: integer):longword; external 'wrapcallback@files:innocallback.dll stdcall';
  121. function FreeArcExtract (callback: longword; cmd1,cmd2,cmd3,cmd4,cmd5,cmd6,cmd7,cmd8,cmd9,cmd10: PAnsiChar): integer; external 'FreeArcExtract@files:unarc.dll cdecl';
  122.  
  123. procedure AppProcessMessage;
  124. var
  125. Msg: TMyMsg;
  126. begin
  127. while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do begin
  128. TranslateMessage(Msg);
  129. DispatchMessage(Msg);
  130. end;
  131. end;
  132.  
  133. // Перевод числа в строку с точностью 3 знака (%.3n) с округлением дробной части, если она есть
  134. Function NumToStr(Float: Extended): String;
  135. Begin
  136. Result:= Format('%.3n', [Float]); StringChange(Result, ',', '.');
  137. while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Length(Result) > 1) do
  138. SetLength(Result, Length(Result)-1);
  139. End;
  140.  
  141. function cm(Message: String): String; Begin Result:= ExpandConstant('{cm:'+ Message +'}') End;
  142.  
  143. Function Size64(Hi, Lo: Integer): Extended;
  144. Begin
  145. Result:= Lo;
  146. if Lo<0 then Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
  147. for Hi:= Hi-1 Downto 0 do
  148. Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
  149. End;
  150.  
  151. // Converts OEM encoded string into ANSI
  152. // Преобразует OEM строку в ANSI кодировку
  153. function OemToAnsiStr( strSource: AnsiString): AnsiString;
  154. var
  155. nRet : longint;
  156. begin
  157. SetLength( Result, Length( strSource ) );
  158. nRet:= OemToChar( strSource, Result );
  159. end;
  160.  
  161. // Converts ANSI encoded string into UTF-8
  162. // Преобразует строку из ANSI в UTF-8 кодировку
  163. function AnsiToUtf8( strSource: string ): string;
  164. var
  165. nRet : integer;
  166. WideCharBuf: string;
  167. MultiByteBuf: string;
  168. begin
  169. strSource:= strSource + chr(0);
  170. SetLength( WideCharBuf, Length( strSource ) * 2 );
  171. SetLength( MultiByteBuf, Length( strSource ) * 2 );
  172.  
  173. nRet:= MultiByteToWideChar( CP_ACP, 0, strSource, -1, WideCharBuf, Length(WideCharBuf) );
  174. nRet:= WideCharToMultiByte( CP_UTF8, 0, WideCharBuf, -1, MultiByteBuf, Length(MultiByteBuf), 0, 0);
  175.  
  176. Result:= MultiByteBuf;
  177. end;
  178.  
  179. // OnClick event function for btnCancel
  180. procedure btnCancelUnpackingOnClick(Sender: TObject);
  181. begin
  182. if MsgBox( SetupMessage( msgExitSetupMessage ), mbInformation, MB_YESNO ) = IDYES then
  183. CancelCode:= -127;
  184. end;
  185.  
  186. var origsize: Integer;
  187. // The callback function for getting info about FreeArc archive
  188. function FreeArcInfoCallback (what: PAnsiChar; Mb, sizeArc: Integer; str: PAnsiChar): Integer;
  189. begin
  190. if string(what)='origsize' then origsize := Mb else
  191. if string(what)='compsize' then else
  192. if string(what)='total_files' then else
  193. Result:= CancelCode;
  194. end;
  195.  
  196. // Returns decompressed size of files in archive
  197. function ArchiveOrigSize(arcname: string): Integer;
  198. var
  199. callback: longword;
  200. Begin
  201. callback:= WrapFreeArcCallback(@FreeArcInfoCallback,4); //FreeArcInfoCallback has 4 arguments
  202. CancelCode:= 0;
  203. AppProcessMessage;
  204. try
  205. // Pass the specified arguments to 'unarc.dll'
  206. Result:= FreeArcExtract (callback, 'l', '--', AnsiToUtf8(arcname), '', '', '', '', '', '', '');
  207. if CancelCode < 0 then Result:= CancelCode;
  208. if Result >= 0 then Result:= origsize;
  209. except
  210. Result:= -63; // ArcFail
  211. end;
  212. end;
  213.  
  214. // Scans the specified folders for archives and add them to list
  215. function FindArcs(dir: string): Extended;
  216. var
  217. FSR: TFindRec;
  218. Begin
  219. Result:= 0;
  220. if FindFirst(ExpandConstant(dir), FSR) then begin
  221. try
  222. repeat
  223. // Skip everything but the folders
  224. if FSR.Attributes and FILE_ATTRIBUTE_DIRECTORY > 0 then CONTINUE;
  225. n:= GetArrayLength(Arcs);
  226. // Expand the folder list
  227. SetArrayLength(Arcs, n +1);
  228. Arcs[n].Path:= ExtractFilePath(ExpandConstant(dir)) + FSR.Name;
  229. Arcs[n].Size:= Size64(FSR.SizeHigh, FSR.SizeLow);
  230. Result:= Result + Arcs[n].Size;
  231. Arcs[n].OrigSize := ArchiveOrigSize(Arcs[n].Path)
  232. totalUncompressedSize := totalUncompressedSize + Arcs[n].OrigSize
  233. until not FindNext(FSR);
  234. finally
  235. FindClose(FSR);
  236. end;
  237. end;
  238. End;
  239.  
  240. // Sets the TaskBar title
  241. Procedure SetTaskBarTitle(Title: String); var h: Integer;
  242. Begin
  243. h:= GetWindowLong(MainForm.Handle, -8); if h <> 0 then SetWindowText(h, Title);
  244. End;
  245.  
  246. // Converts milliseconds to human-readable time
  247. // Конвертирует милисекунды в человеко-читаемое изображение времени
  248. Function TicksToTime(Ticks: DWord; h,m,s: String; detail: Boolean): String;
  249. Begin
  250. if detail {hh:mm:ss format} then
  251. Result:= PADZ(IntToStr(Ticks/3600000), 2) +':'+ PADZ(IntToStr((Ticks/1000 - Ticks/1000/3600*3600)/60), 2) +':'+ PADZ(IntToStr(Ticks/1000 - Ticks/1000/60*60), 2)
  252. else if Ticks/3600 >= 1000 {more than hour} then
  253. Result:= IntToStr(Ticks/3600000) +h+' '+ PADZ(IntToStr((Ticks/1000 - Ticks/1000/3600*3600)/60), 2) +m
  254. else if Ticks/60 >= 1000 {1..60 minutes} then
  255. Result:= IntToStr(Ticks/60000) +m+' '+ PADZ(IntToStr(Ticks/1000 - Ticks/1000/60*60), 2) +s
  256. else Result:= IntToStr(Ticks/1000) +s {less than one minute}
  257. End;
  258.  
  259. // The main callback function for unpacking FreeArc archives
  260. function FreeArcCallback (what: PAnsiChar; Mb, sizeArc: Integer; str: PAnsiChar): Integer;
  261. var
  262. percents, Remaining: Integer;
  263. s: String;
  264. begin
  265. if GetTickCount - LastTimerEvent > 1000 then begin
  266. // This code will be executed once each 1000 ms (этот код будет выполняться раз в 1000 миллисекунд)
  267. // ....
  268. // End of code executed by timer
  269. LastTimerEvent := LastTimerEvent+1000;
  270. end;
  271.  
  272. if string(what)='filename' then begin
  273. // Update FileName label
  274. lblExtractFileName.Caption:= FmtMessage( cm( 'Extracting' ), [OemToAnsiStr( str )] )
  275. end else if (string(what)='write') and (totalUncompressedSize>0) and (Mb>lastMb) then begin
  276. // Assign to Mb *total* amount of data extracted to the moment from all archives
  277. lastMb := Mb;
  278. Mb := baseMb+Mb;
  279.  
  280. // Update progress bar
  281. WizardForm.ProgressGauge.Position:= Mb;
  282.  
  283. // Show how much megabytes/archives were processed up to the moment
  284. percents:= (Mb*1000) div totalUncompressedSize;
  285. s := FmtMessage(cm('ExtractedInfo'), [IntToStr(Mb), IntToStr(totalUncompressedSize)]);
  286. if GetArrayLength(Arcs)>1 then
  287. s := s + '. '+FmtMessage(cm('ArcInfo'), [IntToStr(n+1), IntToStr(GetArrayLength(Arcs))]);
  288. ExtractFile.Caption := s
  289.  
  290. // Calculate and show current percents
  291. percents:= (Mb*1000) div totalUncompressedSize;
  292. s:= FmtMessage(cm('AllProgress'), [Format('%.1n', [Abs(percents/10)])]);
  293. if Mb > 0 then Remaining:= trunc((GetTickCount - StartInstall) * Abs((totalUncompressedSize - Mb)/Mb)) else Remaining:= 0;
  294. if Remaining = 0 then SetTaskBarTitle(cm('ending')) else begin
  295. s:= s + '. '+FmtMessage(cm('remains'), [TicksToTime(Remaining, cm('hour'), cm('min'), cm('sec'), false)])
  296. SetTaskBarTitle(FmtMessage(cm('taskbar'), [IntToStr(percents/10), TicksToTime(Remaining, 'h', 'm', 's', false)]))
  297. end;
  298. WizardForm.FileNameLabel.Caption := s
  299. end;
  300. AppProcessMessage;
  301. Result:= CancelCode;
  302. end;
  303.  
  304. // Extracts all found archives
  305. function UnPack(Archives: string): Integer;
  306. var
  307. totalCompressedSize: Extended;
  308. callback: longword;
  309. FreeMB, TotalMB: Cardinal;
  310. begin
  311. // Display 'Extracting FreeArc archive'
  312. lblExtractFileName.Caption:= '';
  313. lblExtractFileName.Show;
  314. ExtractFile.caption:= cm('ArcTitle');
  315. ExtractFile.Show;
  316. // Show the 'Cancel unpacking' button and set it as default button
  317. btnCancelUnpacking.Caption:= WizardForm.CancelButton.Caption;
  318. btnCancelUnpacking.Show;
  319. WizardForm.ActiveControl:= btnCancelUnpacking;
  320. WizardForm.ProgressGauge.Position:= 0;
  321. // Get the size of all archives
  322. totalUncompressedSize := 0;
  323. totalCompressedSize := FindArcs(Archives);
  324. WizardForm.ProgressGauge.Max:= totalUncompressedSize;
  325. // Other initializations
  326. callback:= WrapFreeArcCallback(@FreeArcCallback,4); //FreeArcCallback has 4 arguments
  327. StartInstall:= GetTickCount; {время начала распаковки}
  328. LastTimerEvent:= GetTickCount;
  329. baseMb:= 0
  330.  
  331. for n:= 0 to GetArrayLength(Arcs) -1 do
  332. begin
  333. lastMb := 0
  334. CancelCode:= 0;
  335. AppProcessMessage;
  336. try
  337. // Pass the specified arguments to 'unarc.dll'
  338. Result:= FreeArcExtract (callback, 'x', '-o+', '-dp' + AnsiToUtf8( ExpandConstant('{app}') ), '--', AnsiToUtf8(Arcs[n].Path), '', '', '', '', '');
  339. if CancelCode < 0 then Result:= CancelCode;
  340. except
  341. Result:= -63; // ArcFail
  342. end;
  343. baseMb:= baseMb+lastMb
  344.  
  345. // Error occured
  346. if Result <> 0 then
  347. begin
  348. msgError:= FmtMessage(cm('ArcError'), [IntToStr(Result)]);
  349. GetSpaceOnDisk(ExtractFileDrive(ExpandConstant('{app}')), True, FreeMB, TotalMB);
  350. case Result of
  351. -1: if FreeMB < 32 {Мб на диске} then msgError:= SetupMessage(msgDiskSpaceWarningTitle)
  352. else msgError:= msgError + #13#10 + FmtMessage(cm('ArcBroken'), [ExtractFileName(Arcs[n].Path)]);
  353. -127: msgError:= cm('ArcBreak'); //Cancel button
  354. -63: msgError:= cm('ArcFail');
  355. end;
  356. // MsgBox(msgError, mbInformation, MB_OK); //сообщение показывается на странице завершения
  357. Log(msgError);
  358. Break; //прервать цикл распаковки
  359. end;
  360. end;
  361. // Hide labels and button
  362. WizardForm.FileNameLabel.Caption:= '';
  363. lblExtractFileName.Hide;
  364. ExtractFile.Hide;
  365. btnCancelUnpacking.Hide;
  366. end;
  367.  
  368. procedure CurStepChanged(CurStep: TSetupStep);
  369. begin
  370. if CurStep = ssPostInstall then
  371. begin
  372. UnPackError:= UnPack(Archives)
  373. if UnPackError = 0 then
  374. SetTaskBarTitle(SetupMessage(msgSetupAppTitle))
  375. else
  376. begin
  377. // Error occured, uninstall it then
  378. Exec(ExpandConstant('{uninstallexe}'), '/SILENT','', sw_Hide, ewWaitUntilTerminated, n); //откат установки из-за ошибки unarc.dll
  379. SetTaskBarTitle(SetupMessage(msgErrorTitle))
  380. WizardForm.Caption:= SetupMessage(msgErrorTitle) +' - '+ cm('ArcBreak')
  381. end;
  382. end;
  383. end;
  384.  
  385. // стандартный способ отката (не нужна CurPageChanged), но архивы распаковываются до извлечения файлов инсталлятора
  386. // if CurStep = ssInstall then
  387. // if UnPack(Archives) <> 0 then Abort;
  388.  
  389. Procedure CurPageChanged(CurPageID: Integer);
  390. Begin
  391. if (CurPageID = wpFinished) and (UnPackError <> 0) then
  392. begin // Extraction was unsuccessful (распаковщик вернул ошибку)
  393. // Show error message
  394. WizardForm.FinishedLabel.Font.Color:= $0000C0; // red (красный)
  395. WizardForm.FinishedLabel.Height:= WizardForm.FinishedLabel.Height * 2;
  396. WizardForm.FinishedLabel.Caption:= SetupMessage(msgSetupAborted) + #13#10#13#10 + msgError;
  397. end;
  398. End;
  399.  
  400. procedure InitializeWizard();
  401. begin
  402. with WizardForm.ProgressGauge do
  403. begin
  404. // Create a label to show current FileName being extracted
  405. lblExtractFileName:= TLabel.Create(WizardForm);
  406. lblExtractFileName.parent:=WizardForm.InstallingPage;
  407. lblExtractFileName.autosize:=false;
  408. lblExtractFileName.Width:= Width;
  409. lblExtractFileName.top:=Top + ScaleY(35);
  410. lblExtractFileName.Caption:= '';
  411. lblExtractFileName.Hide;
  412.  
  413. // Create a label to show percentage
  414. ExtractFile:= TLabel.Create(WizardForm);
  415. ExtractFile.parent:=WizardForm.InstallingPage;
  416. ExtractFile.autosize:=false;
  417. ExtractFile.Width:= Width;
  418. ExtractFile.top:=lblExtractFileName.Top + ScaleY(16);
  419. ExtractFile.caption:= '';
  420. ExtractFile.Hide;
  421. end;
  422.  
  423. // Create a 'Cancel unpacking' button and hide it for now.
  424. btnCancelUnpacking:=TButton.create(WizardForm);
  425. btnCancelUnpacking.Parent:= WizardForm;
  426. btnCancelUnpacking.SetBounds(WizardForm.CancelButton.Left, WizardForm.CancelButton.top, WizardForm.CancelButton.Width, WizardForm.CancelButton.Height);
  427. btnCancelUnpacking.OnClick:= @btnCancelUnpackingOnClick;
  428. btnCancelUnpacking.Hide;
  429. end;
  430.  
  431.  
  432. [InnoIDE_Settings]
  433. UseRelativePaths=false
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement