; Script generated by the Inno Script Studio Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "Valentina" #define MyAppVersion GetFileVersion('valentina\valentina.exe') #define MyAppPublisher "Roman Telezhynskyi" #define MyAppURL "http://www.valentina-project.org/" #define MyAppExeName "valentina.exe" #define MyAppCopyright "(C) 2013-2016 Valentina project" #define MyDateTimeString GetDateTimeString('yyyymmddhhnnss', '', ''); ; Appstatus: "" = release, "b" = beta, "a" = alpha ; this only modifies the resulting exe name of the installer package ;-) #define MyAppStatus "a" [Setup] ; NOTE: The value of AppId uniquely identifies this application. ; Do not use the same AppId value in installers for other applications. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{7081AEC7-38FC-479F-B712-DB073BB76512} AppName={#MyAppName} AppVersion={#MyAppVersion} AppVerName={#MyAppName} {#MyAppVersion} ;AppVerName={#MyAppName} {#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} DefaultDirName={pf}\{#MyAppName} DefaultGroupName={#MyAppName} LicenseFile=.\LICENSE_VALENTINA InfoAfterFile=.\valentina\README.txt OutputDir=.\ OutputBaseFilename=valentina_{#MyAppVersion}{#MyAppStatus}-{#MyDateTimeString} SetupIconFile=.\valentina\valentina.ico Compression=lzma SolidCompression=yes VersionInfoVersion={#MyAppVersion} ShowLanguageDialog=auto VersionInfoProductName=Valentina AppComments=Patternmaking program AppContact={#MyAppURL} AppCopyright={#MyAppCopyright} ChangesAssociations=yes ;SignTool=MySign ;Uncomment the previous string for code signing ;MySign=signtool.exe sign /v /a /n $qSeamly, LLC$q /t http://timestamp.comodoca.com/authenticode /d $qPatternmaking program$q $f [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" Name: "armenian"; MessagesFile: "compiler:Languages\Armenian.islu" Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl" Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl" Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl" Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl" Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl" Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl" Name: "french"; MessagesFile: "compiler:Languages\French.isl" Name: "german"; MessagesFile: "compiler:Languages\German.isl" Name: "greek"; MessagesFile: "compiler:Languages\Greek.isl" Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl" Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl" Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" Name: "nepali"; MessagesFile: "compiler:Languages\Nepali.islu" Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl" Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl" Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl" Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" Name: "scottishgaelic"; MessagesFile: "compiler:Languages\ScottishGaelic.isl" Name: "serbiancyrillic"; MessagesFile: "compiler:Languages\SerbianCyrillic.isl" Name: "serbianlatin"; MessagesFile: "compiler:Languages\SerbianLatin.isl" Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl" Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl" Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl" Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1 Name: "fileassoc1"; Description: "{cm:CreateFileAssocVal}"; GroupDescription: "{cm:FileAssoc}" Name: "fileassoc2"; Description: "{cm:CreateFileAssocVit}"; GroupDescription: "{cm:FileAssoc}" Name: "fileassoc3"; Description: "{cm:CreateFileAssocVst}"; GroupDescription: "{cm:FileAssoc}" [Files] Source: ".\valentina\valentina.exe"; DestDir: "{app}"; Flags: ignoreversion sign Source: ".\valentina\tape.exe"; DestDir: "{app}"; Flags: ignoreversion sign Source: ".\valentina\vpropertyexplorer.dll"; DestDir: "{app}"; Flags: ignoreversion sign Source: ".\valentina\qmuparser2.dll"; DestDir: "{app}"; Flags: ignoreversion sign Source: ".\valentina\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs ; NOTE: Don't use "Flags: ignoreversion" on any shared system files ; DLL used to check if the target program is running at install time [Icons] Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" Name: "{group}\Tape"; Filename: "{app}\tape.exe" Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon Name: "{commondesktop}\Tape"; Filename: "{app}\tape.exe"; Tasks: desktopicon Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent [Registry] Root: "HKCR"; Subkey: ".val"; ValueType: string; ValueName: ""; ValueData: "Valentina.Pattern"; Flags: uninsdeletevalue; Tasks: fileassoc1 Root: "HKCR"; Subkey: ".vit"; ValueType: string; ValueName: ""; ValueData: "Valentina.IndividualMeasurements"; Flags: uninsdeletevalue; Tasks: fileassoc2 Root: "HKCR"; Subkey: ".vst"; ValueType: string; ValueName: ""; ValueData: "Valentina.StandardMeasurements"; Flags: uninsdeletevalue; Tasks: fileassoc3 Root: "HKCR"; Subkey: "Valentina.Pattern"; ValueType: string; ValueData: "Valentina pattern file"; Flags: uninsdeletekey; Tasks: fileassoc1 Root: "HKCR"; Subkey: "Valentina.Pattern\DefaultIcon"; ValueType: string; ValueData: "{app}\pattern.ico,0"; Tasks: fileassoc1 Root: "HKCR"; Subkey: "Valentina.Pattern\shell\open\command"; ValueType: string; ValueData: """{app}\valentina.exe"" ""%1"""; Tasks: fileassoc1 Root: "HKCR"; Subkey: "Valentina.IndividualMeasurements"; ValueType: string; ValueData: "Valentina individual measurement file"; Flags: uninsdeletekey; Tasks: fileassoc2 Root: "HKCR"; Subkey: "Valentina.IndividualMeasurements\DefaultIcon"; ValueType: string; ValueData: "{app}\i-measurements.ico,0"; Tasks: fileassoc2 Root: "HKCR"; Subkey: "Valentina.IndividualMeasurements\shell\open\command"; ValueType: string; ValueData: """{app}\tape.exe"" ""%1"""; Tasks: fileassoc2 Root: "HKCR"; Subkey: "Valentina.StandardMeasurements"; ValueType: string; ValueData: "Valentina standard measurement file"; Flags: uninsdeletekey; Tasks: fileassoc3 Root: "HKCR"; Subkey: "Valentina.StandardMeasurements\DefaultIcon"; ValueType: string; ValueData: "{app}\s-measurements.ico,0"; Tasks: fileassoc3 Root: "HKCR"; Subkey: "Valentina.StandardMeasurements\shell\open\command"; ValueType: string; ValueData: """{app}\tape.exe"" ""%1"""; Tasks: fileassoc3 [CustomMessages] FileAssoc=Create file associations CreateFileAssocVal=*.val (Pattern file) CreateFileAssocVit=*.vit (Individual measurement file) CreateFileAssocVst=*.vst (Standard measurement file) WarnRemoveOld= is installed at the moment. Remove old version? WarnSameVersionExit= is already installed. This installer will exit. WarnRunningOnUnInstall1= is currently running. WarnRunningOnUnInstall2=Please close it and then click on ''Retry'' to proceed. WarnCancelInstall=The installation was canceled. WarnCancelUninstall=The uninstallation process was canceled. WarnOverwrite= is already installed. Overwrite existing installation? SetupIsRunningWarning = Valentina setup is already running! DeinstIsRunningWarning = Valentina uninstall is already running! [Code] const // Executable names to check before any setup/uninstall operation ProgramName1 = 'Valentina'; ProgramExeName1 = 'valentina.exe'; ProgramName2 = 'Tape'; ProgramExeName2 = 'tape.exe'; ///////////////////////////////////////////////////////////////////// // Convert version strings into float and compare // easier than string comparison function CompareVersion(str1, str2: String): Integer; var temp1, temp2: String; num1, num2 : Variant; begin temp1 := str1; temp2 := str2; StringChangeEx(temp1, '.', '', True); StringChangeEx(temp2, '.', '', True); num1 := 100*StrToFloat(temp1); num2 := 100*StrToFloat(temp2); Result := num1 - num2 end; // Global variables/constants and general functions const installer_mutex_name = '{#MyAppName}' + '_setup_mutex'; const uninstaller_mutex_name = '{#MyAppName}' + '_uninstall_mutex'; ///////////////////////////////////////////////////////////////////// // Find application by name in current process list // -> AppName: Name of running exe file // <- True if the program found, False if not function FindApp(const AppName: String): Boolean; var WMIService: Variant; WbemLocator: Variant; WbemObjectSet: Variant; begin WbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); WMIService := WbemLocator.ConnectServer('localhost', 'root\CIMV2'); WbemObjectSet := WMIService.ExecQuery('SELECT * FROM Win32_Process Where Name="' + AppName + '"'); if not VarIsNull(WbemObjectSet) and (WbemObjectSet.Count > 0) then begin Result := True; end else begin Result := False; end; end; ///////////////////////////////////////////////////////////////////// // Prompt the user to close a program that's still running. // Finish when the executable is closed or the user cancels the process. // -> ProgramExeName: Name of executable // -> Message : User message to prompt to close // <- True if the program was closed (or was not running), // False if the user clicked on the Cancel button and didn't close the program function PromptUntilProgramClosedOrInstallationCanceled( ProgramExeName: String; Message: String ): Boolean; var ButtonPressed : Integer; begin ButtonPressed := IDRETRY; // Check if the program is running or if the user has pressed the cancel button while FindApp( ProgramExeName ) and ( ButtonPressed <> IDCANCEL ) do begin ButtonPressed := MsgBox( message , mbError, MB_RETRYCANCEL ); end; // Has the program been closed? Result := Not FindApp( ProgramExeName ); end; ///////////////////////////////////////////////////////////////////// // Version comparison on installation function VersionCompareAndUninstall(): Boolean; var oldVersion: String; uninstaller: String; ErrorCode: Integer; tmpId : String; begin tmpId := '{#emit SetupSetting("AppId")}'; Delete(tmpId,1,1); if RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + tmpId + '_is1') then begin RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + tmpId + '_is1', 'DisplayVersion', oldVersion); if (CompareVersion(oldVersion, '{#emit SetupSetting("AppVersion")}') < 0) then begin if MsgBox('Version ' + oldVersion + ExpandConstant('{cm:WarnRemoveOld}'), mbConfirmation, MB_YESNO) = IDNO then begin Result := False; end else begin RegQueryStringValue(HKEY_LOCAL_MACHINE,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + tmpId + '_is1','UninstallString', uninstaller); If ShellExec('', uninstaller, '/SILENT', '', SW_SHOW, ewWaitUntilTerminated, ErrorCode) then begin // handle success if necessary; ResultCode contains the exit code Result := True end else begin // handle failure if necessary; ResultCode contains the error code Result := False end end; end else begin //MsgBox('Version ' + oldVersion + ExpandConstant('{cm:WarnSameVersionExit}'),mbInformation, MB_OK); if MsgBox('Version ' + oldVersion + ExpandConstant('{cm:WarnOverwrite}'), mbConfirmation, MB_YESNO) = IDNO then Result := False else Result := True; end; end else begin Result := True; end; end; ///////////////////////////////////////////////////////////////////// // Run on setup function InitializeSetup(): Boolean; var // User messages ProgramRunningOnInstallMessage : String; InstallationCanceledMessage : String; begin // Create a mutex for the installer and if it's already running then show a message and stop installation if CheckForMutexes(installer_mutex_name) then begin SuppressibleMsgBox(ExpandConstant('{cm:SetupIsRunningWarning}'), mbError, MB_OK, MB_OK); Result := False; end else begin Result := True; CreateMutex(installer_mutex_name); ProgramRunningOnInstallMessage := ExpandConstant('{cm:WarnRunningOnUnInstall1}') + #13 + #13 + ExpandConstant('{cm:WarnRunningOnUnInstall2}'); InstallationCanceledMessage := ExpandConstant('{cm:WarnCancelInstall}'); Result := PromptUntilProgramClosedOrInstallationCanceled( ProgramExeName1, ProgramName1 + ProgramRunningOnInstallMessage) If Result Then begin Result := PromptUntilProgramClosedOrInstallationCanceled( ProgramExeName2, ProgramName2 + ProgramRunningOnInstallMessage) end; if Not Result then begin MsgBox( InstallationCanceledMessage, mbInformation, MB_OK ); end else begin Result := VersionCompareAndUninstall end; end; end; ///////////////////////////////////////////////////////////////////// // Run on uninstall function InitializeUninstall(): Boolean; var // User message ProgramRunningOnUninstallMessage : String; UninstallationCanceledMessage : String; begin if CheckForMutexes(uninstaller_mutex_name) then begin SuppressibleMsgBox(ExpandConstant('{cm:DeinstIsRunningWarning}'), mbError, MB_OK, MB_OK); Result := False; end else begin Result := True; CreateMutex(uninstaller_mutex_name); ProgramRunningOnUninstallMessage := ExpandConstant('{cm:WarnRunningOnUnInstall1}') + #13 + #13 + ExpandConstant('{cm:WarnRunningOnUnInstall2}'); UninstallationCanceledMessage := ExpandConstant('{cm:WarnCancelUninstall}'); Result := PromptUntilProgramClosedOrInstallationCanceled( ProgramExeName1, ProgramName1 + ProgramRunningOnUninstallMessage); If Result Then begin Result := PromptUntilProgramClosedOrInstallationCanceled( ProgramExeName2, ProgramName2 + ProgramRunningOnUninstallMessage); end; if not Result then begin MsgBox( UninstallationCanceledMessage, mbInformation, MB_OK ); end; end; end;