Advertisement
Guest User

inno setup

a guest
Jan 16th, 2024
394
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.49 KB | None | 0 0
  1. ; Script generated by the Inno Setup Script Wizard.
  2. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
  3.  
  4. #define MyAppName "Stable Projectorz"
  5. #define MyAppVersion "1.1.2"
  6. #define MyAppPublisher "Igor Aherne"
  7. #define MyAppURL "https://stableprojectorz.com"
  8. #define MyAppExeName "Stable Projectorz.exe"
  9. #define MyAppAssocName MyAppName + " File"
  10. #define MyAppAssocExt ".strz"
  11. #define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt
  12.  
  13. [Setup]
  14. ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
  15. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
  16. AppId=COMMENTED OUT FOR REDDIT
  17. AppName={#MyAppName}
  18. AppVersion={#MyAppVersion}
  19. SetupIconFile=icon.ico
  20. ;AppVerName={#MyAppName} {#MyAppVersion}
  21. AppPublisher={#MyAppPublisher}
  22. AppPublisherURL={#MyAppURL}
  23. AppSupportURL={#MyAppURL}
  24. AppUpdatesURL={#MyAppURL}
  25. ; NOTE: THIS WON'T WORK: DefaultDirName={autopf}\{#MyAppName} Because our 'webui-user.bat' won't be able to run inside Program Files (due to UAC on user computers). Therefore using {userdocs}
  26. DefaultDirName={userdocs}\{#MyAppName}
  27. ChangesAssociations=yes
  28.  
  29. ; commented out because if AppId (see above) is already found on user machine, we need to update it into the same dir,
  30. ; rather than letting them install it elsewhere. (would need user to re-donwload webui nets). Also, new users will need to select dir anyway.
  31. ; This is important becuse DisableDirPage=no forces users to pick dir even if updating. And DisableDirPage=yes will install into into incompatible dir for the new users (Program Files) where StableProjectorz can't run.
  32. ;DisableDirPage=no
  33.  
  34. DisableWelcomePage=no
  35. WizardImageFile=InstallerIllustration.bmp
  36. WizardStyle=modern
  37.  
  38. DisableProgramGroupPage=yes
  39. ; Remove the following line to run in administrative install mode (install for all users.);
  40. PrivilegesRequired=admin
  41. PrivilegesRequiredOverridesAllowed=commandline
  42. OutputDir=C:\_myDrive\repos\StableDiffusion_unity\InnoSetup
  43. ; Will be compiling into StableProjectorz_v1_(Installer).exe
  44. OutputBaseFilename=StableProjectorz_v1_1_2(Installer)
  45. Compression=lzma
  46. SolidCompression=yes
  47.  
  48. LicenseFile=License.rtf
  49. InfoBeforeFile=CurrentVersionFeatures.rtf
  50.  
  51. ; IMPORTANT!!! Otherwise cmd prompt isn't restarted. And git (that was just installed) wont't avaialble in any child cmd prompts that are initiated after/by the installer.
  52. AlwaysRestart=yes
  53.  
  54.  
  55. [Languages]
  56. Name: "english"; MessagesFile: "compiler:Default.isl"
  57.  
  58. [Tasks]
  59. Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
  60.  
  61. [Files]
  62. Source: "C:\_myDrive\repos\StableDiffusion_unity\Builds\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
  63. Source: "C:\_myDrive\repos\StableDiffusion_unity\Builds\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
  64. Source: "Dependencies\TEST MESHES\*"; DestDir: "{app}\TEST MESHES"; Flags: ignoreversion recursesubdirs createallsubdirs
  65. Source: "Dependencies\python-3.10.6-amd64.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall
  66. Source: "Dependencies\stable-diffusion-webui-master.zip"; DestDir: "{tmp}"; Flags: deleteafterinstall
  67. ; NOTE: Don't use "Flags: ignoreversion" on any shared system files
  68.  
  69. [Registry]
  70. Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue
  71. Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey
  72. Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
  73. Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""
  74. Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".myp"; ValueData: ""
  75.  
  76. [Icons]
  77. Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
  78. Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
  79.  
  80.  
  81. [Run]
  82. Filename: "{tmp}\python-3.10.6-amd64.exe"; Parameters: "/quiet InstallAllUsers=1 PrependPath=1"; WorkingDir: "{tmp}"; Flags: runhidden waituntilterminated; Check: not PythonIsAlreadyInstalled; AfterInstall: GetPythonInstallPath; StatusMsg: "Installing Python 3.10.6, please wait..."
  83. Filename: "{tmp}\Git-2.43.0-64-bit.exe"; Parameters: "/SILENT"; Check: not IsGitInstalled; StatusMsg: "Downloading + Installing Git, please wait...";
  84. Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent; StatusMsg: "Finalizing installation..."
  85. ; NOTE: Check: not isWebUINotNeeded ensures we won't unpack nor update the webui repo, if it already exists in the destination folder. User might have large neural nets there. Also, the order of parameters isn't important, don't worry that 'Check:' is last in that line:
  86. Filename: "powershell.exe"; Parameters: "-NoProfile -ExecutionPolicy Bypass -Command ""Expand-Archive -LiteralPath '{tmp}\stable-diffusion-webui-master.zip' -DestinationPath '{app}'"""; Flags: runhidden; StatusMsg: "Extracting stable-diffusion-webui..."; AfterInstall: UpdateWebUIUserBatFile; Check: not IsWebUINotNeeded
  87.  
  88.  
  89.  
  90. [Code]
  91.  
  92. function OnDownloadProgress(const Url, FileName: String; const Progress, ProgressMax: Int64): Boolean;
  93. begin
  94. Result := True;
  95. end;
  96.  
  97.  
  98. var
  99. ProgramFiles32Dir: string;
  100. ProgramFiles64Dir: string;
  101. DownloadPage: TDownloadWizardPage;
  102.  
  103. function InitializeSetup(): Boolean;
  104. begin
  105. // Expand constants for directory checking
  106. ProgramFiles32Dir := ExpandConstant('{pf32}');
  107. ProgramFiles64Dir := ExpandConstant('{pf64}');
  108.  
  109. Result := True;
  110. end;
  111.  
  112.  
  113.  
  114. // InitializeWizard() is a special event function that is automatically called by the Inno Setup engine
  115. // during the installation process. You don't need to explicitly invoke it yourself.
  116. // Shows a custom page at the start of the installation with the illustration. Makes it look professional:)
  117. procedure InitializeWizard;
  118. begin
  119. // Initialize the download page for Git
  120. DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), @OnDownloadProgress);
  121.  
  122. // Hide the default welcome labels
  123. WizardForm.WelcomeLabel2.Visible := True;
  124. WizardForm.WelcomeLabel2.Caption := 'This will install Stable Projectorz version 1.1.2 on your computer.' + #13#10
  125. + 'Will also install dependencies: Github (Git) and Python 3.10.6' + #13#10 + #13#10 + 'It is recommended that you close all other applications before continuing.'
  126. + #13#10 + #13#10 + #13#10 + 'Stable Projectorz is a free tool for texturing 3d models using AI, on your own computer.' + #13#10 + #13#10 +
  127. 'It runs Stable Diffusion on your computer (via Automatic1111 webui) to generate images.' + #13#10 + #13#10 +
  128. 'See https://stableprojectorz.com for tutorials, tips and our Discord community.'+ #13#10 + #13#10 + 'Version 1.1.2 (Jan 2024)';
  129. end;
  130.  
  131.  
  132.  
  133. function IsGitInstalled: Boolean;
  134. var
  135. ErrorCode: Integer;
  136. begin
  137. // Check if 'git --version' command can be executed successfully
  138. Result := Exec('git', '--version', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode) and (ErrorCode = 0);
  139. end;
  140.  
  141.  
  142.  
  143. function NextButtonClick(CurPageID: Integer): Boolean;
  144. var
  145. SelectedDir: string;
  146. ErrorCode: Integer;
  147. begin
  148. Result := True;
  149.  
  150. // Check for directory selection
  151. if CurPageID = wpSelectDir then
  152. begin
  153. SelectedDir := WizardDirValue(); // Get the selected directory
  154.  
  155. // Prevent user from selecting destination to be `Program Files` or `Program Files (x86)`.
  156. // This will allow our webui to correctly run, and download torch, stablediffusion etc.
  157. // Check if the selected directory is under Program Files.
  158. if (Pos(ProgramFiles32Dir, SelectedDir) = 1) or
  159. (Pos(ProgramFiles64Dir, SelectedDir) = 1) then
  160. begin
  161. MsgBox('Installing Stable Projectorz in the Program Files directory may be restrictive. Please select a different destination directory that Windows won''t worry about. For example, C:\Users\Yourname\Documents\', mbError, MB_OK);
  162. Result := False; // Prevent moving to the next page
  163. Exit;
  164. end;
  165. end;
  166.  
  167. // Check for ready to install page and download/install Git if needed
  168. if (CurPageID = wpReady) then
  169. begin
  170. if not IsGitInstalled then
  171. begin
  172. DownloadPage.Clear;
  173. DownloadPage.Add('https://github.com/git-for-windows/git/releases/download/v2.43.0.windows.1/Git-2.43.0-64-bit.exe', 'Git-2.43.0-64-bit.exe', '');
  174. DownloadPage.Show;
  175.  
  176. try
  177. try
  178. DownloadPage.Download;
  179. if not Exec(ExpandConstant('{tmp}\Git-2.43.0-64-bit.exe'), '/SILENT', '', SW_SHOW, ewWaitUntilTerminated, ErrorCode) then
  180. begin
  181. // Handle the error if Git installer fails
  182. MsgBox('Failed to install Git: ' + SysErrorMessage(ErrorCode), mbError, MB_OK);
  183. end;
  184. except
  185. SuppressibleMsgBox('Failed to download Git Installer: ' + GetExceptionMessage, mbCriticalError, MB_OK, IDOK);
  186. Result := False;
  187. end;
  188. finally
  189. DownloadPage.Hide;
  190. end;
  191. end;
  192. end;
  193.  
  194. end;
  195.  
  196.  
  197.  
  198.  
  199. function IsWebUINotNeeded: Boolean;
  200. var
  201. WebUIDir: string;
  202. FindRec: TFindRec;
  203. begin
  204. WebUIDir := ExpandConstant('{app}\stable-diffusion-webui-master');
  205. // Check if the directory exists
  206. Result := DirExists(WebUIDir);
  207. // If the directory exists, check for files/subdirectories
  208. if Result then
  209. begin
  210. if FindFirst(WebUIDir + '\*', FindRec) then
  211. begin
  212. // Found files or subdirectories, so no need to unpack
  213. Result := True;
  214. FindClose(FindRec);
  215. end
  216. else
  217. begin
  218. // No files or subdirectories found, need to unpack
  219. Result := False;
  220. end;
  221. end;
  222. end;
  223.  
  224.  
  225.  
  226.  
  227. var
  228. PythonInstallPath: string;// a global variable to store the Python path
  229.  
  230.  
  231.  
  232. procedure LogMessage(Message: string);
  233. begin
  234. MsgBox(Message, mbInformation, MB_OK);
  235. end;
  236.  
  237. //will run after the Python installer (AfterInstall: GetPythonInstallPath).
  238. //It attempts to find the installation path from the registry.
  239. //If it's not found, you can either fall back to a default path or handle the error as needed.
  240. procedure GetPythonInstallPath;
  241. var
  242. InstallPath, PythonExe: string;
  243. begin
  244.  
  245. // First, try to get the full path to the Python executable
  246. if not RegQueryStringValue(HKLM64, 'Software\Python\PythonCore\3.10\InstallPath', 'ExecutablePath', InstallPath) and
  247. not RegQueryStringValue(HKLM, 'Software\Python\PythonCore\3.10\InstallPath', 'ExecutablePath', InstallPath) and
  248. not RegQueryStringValue(HKCU64, 'Software\Python\PythonCore\3.10\InstallPath', 'ExecutablePath', InstallPath) and
  249. not RegQueryStringValue(HKCU, 'Software\Python\PythonCore\3.10\InstallPath', 'ExecutablePath', InstallPath) then
  250. begin
  251. // If ExecutablePath is not found, try to use the default InstallPath and append python.exe
  252. if RegQueryStringValue(HKLM64, 'Software\Python\PythonCore\3.10\InstallPath', '', InstallPath) or
  253. RegQueryStringValue(HKLM, 'Software\Python\PythonCore\3.10\InstallPath', '', InstallPath) or
  254. RegQueryStringValue(HKCU64, 'Software\Python\PythonCore\3.10\InstallPath', '', InstallPath) or
  255. RegQueryStringValue(HKCU, 'Software\Python\PythonCore\3.10\InstallPath', '', InstallPath) then
  256. begin
  257. InstallPath := AddBackslash(InstallPath) + 'python.exe';
  258. end
  259. else
  260. begin
  261. InstallPath := '';
  262. end;
  263. end;
  264.  
  265. PythonInstallPath := InstallPath;
  266. end;
  267.  
  268.  
  269.  
  270. //---------------------------------------------------------------------------------------
  271. //---------------------------------------------------------------------------------------
  272. // CHECKING IF USER HAS 3.10 (any path will do)
  273. // and installing our python otherwise (included into the installer)
  274. // This will be needed for the Automatic1111 StableDiffusion web-ui
  275. //---------------------------------------------------------------------------------------
  276. //---------------------------------------------------------------------------------------
  277.  
  278. function ParseVersion(const VersionString: string; out Major, Minor, Patch: Integer): Boolean;
  279. var
  280. DotPos: Integer;
  281. Remaining: string;
  282. begin
  283. Result := False;
  284. DotPos := Pos('.', VersionString);
  285. if DotPos = 0 then exit;
  286.  
  287. Major := StrToIntDef(Copy(VersionString, 1, DotPos - 1), 0);
  288. Remaining := Copy(VersionString, DotPos + 1, Length(VersionString));
  289.  
  290. DotPos := Pos('.', Remaining);
  291. if DotPos > 0 then
  292. begin
  293. Minor := StrToIntDef(Copy(Remaining, 1, DotPos - 1), 0);
  294. Patch := StrToIntDef(Copy(Remaining, DotPos + 1, Length(Remaining)), 0);
  295. end
  296. else
  297. begin
  298. Minor := StrToIntDef(Remaining, 0);
  299. Patch := 0;
  300. end;
  301.  
  302. Result := True;
  303. end;
  304.  
  305. //does not check for an exact version match, but rather checks if the installed version
  306. // meets my criteria (major version 3, minor version 10, and patch version 6 or higher)
  307. // It will also return the Python installation path
  308. function checkKey(RegPart: Integer; const KeyBase: string; ReqMajor, ReqMinor, ReqPatch: Integer; var InstallPath: string): Boolean;
  309. var
  310. SubKeys: TArrayOfString;
  311. I: Integer;
  312. Key, InstalledVersion: string;
  313. Major, Minor, Patch: Integer;
  314. begin
  315. Result := False;
  316. InstallPath := '';
  317. if RegGetSubkeyNames(RegPart, KeyBase, SubKeys) then
  318. begin
  319. for I := 0 to GetArrayLength(SubKeys) - 1 do
  320. begin
  321. Key := KeyBase + '\' + SubKeys[I];
  322. if RegQueryStringValue(RegPart, Key, 'Version', InstalledVersion) and
  323. ParseVersion(InstalledVersion, Major, Minor, Patch) then
  324. begin
  325. if (Major = ReqMajor) and (Minor = ReqMinor) and (Patch >= ReqPatch) then
  326. begin
  327. if RegQueryStringValue(RegPart, Key, 'InstallPath', InstallPath) then
  328. begin
  329. Result := True;
  330. Break;
  331. end;
  332. end;
  333. end;
  334. end;
  335. end;
  336. end;
  337.  
  338.  
  339. function PythonIsAlreadyInstalled: Boolean;
  340. var
  341. InstallPath: string;
  342. begin
  343. // Check for both 32-bit and 64-bit installations, for all users and current user.
  344. Result := checkKey(HKEY_LOCAL_MACHINE, 'Software\Python\PythonCore\3.10', 3, 10, 6, InstallPath) or
  345. checkKey(HKEY_LOCAL_MACHINE, 'Software\Wow6432Node\Python\PythonCore\3.10', 3, 10, 6, InstallPath) or
  346. checkKey(HKEY_CURRENT_USER, 'Software\Python\PythonCore\3.10', 3, 10, 6, InstallPath) or
  347. checkKey(HKEY_CURRENT_USER, 'Software\Wow6432Node\Python\PythonCore\3.10', 3, 10, 6, InstallPath);
  348.  
  349. // Store the installation path in a global variable if Python is found
  350. if Result then
  351. PythonInstallPath := InstallPath;
  352. end;
  353.  
  354.  
  355. function IsPythonVersionSuitable(Major, Minor, Patch: Integer): Boolean;
  356. begin
  357. // Accept 3.10.x where x >= 6. Does not accept 3.11 and above
  358. Result := (Major = 3) and (Minor = 10) and (Patch >= 6);
  359. end;
  360.  
  361.  
  362. function IsPythonVersionSuitableFromStr(const VersionString: string; ReqMajor, ReqMinor, ReqPatch: Integer): Boolean;
  363. var
  364. Major, Minor, Patch: Integer;
  365. begin
  366. if not ParseVersion(VersionString, Major, Minor, Patch) then
  367. Result := False
  368. else
  369. Result := IsPythonVersionSuitable(Major, Minor, Patch);
  370. end;
  371.  
  372.  
  373. // After the webui.zip is unpacked we need to modify its .bat file contents.
  374. // This will make use of the python-path variable (PythonInstallPath) that we've located earlier.
  375. //we will also add extra arguments in there, such as --ap and --xformers
  376. // And I want that path to be assigned inside the webui.bat correctly.
  377. // For example `C:\Program Files (x86)\StableProjectorz\stable-diffusion-webui-master\webui-user.bat`it looks as this by default (but might have some values already.
  378. procedure UpdatePythonPathInBatchFile(var Lines: TStringList; const PythonInstallPath: string);
  379. var
  380. I: Integer;
  381. UpdatedPath, PythonExe: string;
  382. begin
  383. PythonExe := '\python.exe';
  384. UpdatedPath := PythonInstallPath;
  385.  
  386. // Ensure the path ends with \python.exe
  387. if (Length(UpdatedPath) < Length(PythonExe)) or
  388. (Copy(UpdatedPath, Length(UpdatedPath) - Length(PythonExe) + 1, Length(PythonExe)) <> PythonExe) then
  389. begin
  390. UpdatedPath := UpdatedPath + PythonExe;
  391. end;
  392.  
  393. // Enclose the path in double quotes to avoid issues if it contains spaces.
  394. UpdatedPath := '"' + UpdatedPath + '"';
  395.  
  396. // Update or add the PYTHON path line
  397. for I := 0 to Lines.Count - 1 do
  398. begin
  399. if Pos('set PYTHON=', Lines[I]) = 1 then
  400. begin
  401. Lines[I] := 'set PYTHON=' + UpdatedPath;
  402. Exit;
  403. end;
  404. end;
  405.  
  406. // If PYTHON line is not found, add it
  407. Lines.Add('set PYTHON=' + UpdatedPath);
  408. end;
  409.  
  410.  
  411. procedure UpdateWebUIUserBatFile;
  412. var
  413. FileName: String;
  414. Lines: TStringList;
  415. begin
  416. FileName := ExpandConstant('{app}\stable-diffusion-webui-master\webui-user.bat');
  417. if not FileExists(FileName) then
  418. Exit;
  419.  
  420. Lines := TStringList.Create;
  421. try
  422. Lines.LoadFromFile(FileName);
  423.  
  424. UpdatePythonPathInBatchFile(Lines, PythonInstallPath);
  425.  
  426. Lines.SaveToFile(FileName);
  427. finally
  428. Lines.Free;
  429. end;
  430. end;
  431.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement