Kreni od Inno Setup sajta, odnosno njegovog indeksa.
Program i pomoćni alati
- Downloads
Linkovi sa dokumentacijom: (ovde ćeš naći odgovore na većinu nedoumica)
- Documentation
- FAQ
- Knowledge Base
Prevodi za mnoge jezike (Tu ćeš pronaći i našu latinicu, kao i ćirilicu, pod uslovom da se koristi Unicode verzija programa)
- Translations
Newsgrupe (Zvanična podrška. Ovde možeš rešiti sve dnevne nedoumice u vezi instalera, skripti, alata, ...)
- Newsgroups
Od neznavičnih, a izuzetno korisnih linkova u vezi InnoSetup-a, izdvajam:
Inno Setup Extensions Knowledge Base
Evo par sporadičnih naslova sa tog linka:
Service - Functions to Start, Stop, Install, Remove a Service
Detect if an application is running
.NET - Detect framework
...
I konačno, evo jedne konkretne skripte (u kojoj sam se pored ostalog borio i sa greškama u projektovanju skripte, jer sam je loše zamislio u startu, a trebalo je zadržati kompatibilnost na niže)
;retrieve version of the program from exe
#define AppVersion GetFileVersion(AddBackslash(SourcePath) + "..\..\di.exe")
[Languages]
Name: mytrans; MessagesFile: "compiler:Serbian.isl"
[Registry]
Root: HKLM; Subkey: "Software\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "Di dictionary"; ValueData: "{app}"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\MenuExt\Prevedi sa Di recnikom"; ValueType: string; ValueData: "{app}\diie.htm"; Flags: uninsdeletekey
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\MenuExt\Prevedi sa Di recnikom"; ValueType: dword; ValueName: "contexts"; ValueData: "$10"; Flags: uninsdeletekey
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\MenuExt\Translate with Di dictionary"; ValueType: string; ValueData: ""; Flags: uninsdeletekey
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\MenuExt\Translate with Di dictionary"; ValueType: dword; ValueName: "contexts"; ValueData: "$10"; Flags: uninsdeletekey
[Setup]
AppMutex={code:DetermineIfToSetMutex}
AppID=Di recnik
AppName=Di rečnik
AppVerName=Di rečnik, v{#AppVersion}
AppPublisher=Antivari Software Design, s.a.
AppPublisherURL=http://www.antivari.com
AppSupportURL=http://www.antivari.com
AppUpdatesURL=http://www.antivari.com
DefaultDirName={code:GetPrevDir|{pf}\Di recnik}
DefaultGroupName={code:GetPrevGrp|Di recnik}
AllowNoIcons=no
OutputDir=E:\Code\Borland\BCB6\Di\Setups\Serbian\Setup
OutputBaseFilename=setup_sr
LicenseFile=E:\Code\Borland\BCB6\Di\Setups\Serbian\License.txt
SetupIconFile=E:\Code\Borland\BCB6\Di\Setups\DI.ICO
WizardSmallImageFile=E:\Code\Borland\BCB6\Di\Setups\right_up.bmp
WizardImageFile=E:\Code\Borland\BCB6\Di\Setups\left.bmp
Compression=lzma
SolidCompression=yes
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "E:\Code\Borland\BCB6\Di\Di.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\Code\Borland\BCB6\Di\Setups\di.mdb"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\Code\borland\bcb6\Di\AddCode\JScript\diie.htm"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\Code\Borland\BCB6\Di\Setups\Serbian\Di.ini"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\Code\Borland\BCB6\Di\Setups\Borlndmm.dll"; DestDir: "{sys}"; Flags: sharedfile
Source: "E:\Code\Borland\BCB6\Di\Setups\cc3260mt.dll"; DestDir: "{sys}"; Flags: sharedfile
Source: "E:\Code\Borland\BCB6\Di\Setups\cc3260.dll"; DestDir: "{sys}"; Flags: sharedfile
Source: "E:\Code\Borland\BCB6\Di\Setups\vcl60.bpl"; DestDir: "{sys}"; Flags: sharedfile
Source: "E:\Code\Borland\BCB6\Di\Setups\rtl60.bpl"; DestDir: "{sys}"; Flags: sharedfile
Source: "E:\Code\Borland\BCB6\Di\Setups\adortl60.bpl"; DestDir: "{sys}"; Flags: sharedfile
Source: "E:\Code\borland\bcb6\Di\AddCode\altfhook\ALTFHOOK.DLL"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\Code\Borland\BCB6\Di\Setups\LHTTSENG.EXE"; DestDir: "{app}"; Flags: deleteafterinstall
Source: "E:\Code\Borland\BCB6\Di\Setups\SPCHAPI.EXE"; DestDir: "{app}"; Flags: deleteafterinstall
Source: "E:\Code\borland\bcb6\Di\AddCode\diie\diie.exe"; DestDir: "{app}"; Flags: deleteafterinstall
Source: "E:\Code\Borland\BCB6\Di\Setups\Serbian\Manual.pdf"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\Code\borland\bcb6\Di\Setups\Chm_and_Web\CHM\Serbian\Di.chm"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\Code\Borland\BCB6\Di\Setups\Serbian\History of changes.txt"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\Code\Borland\BCB6\Di\Setups\Serbian\Known bugs.txt"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\Code\Borland\BCB6\Di\Setups\Serbian\License.txt"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\Di recnik"; Filename: "{app}\Di.exe"
Name: "{group}\Pomoc"; Filename: "{app}\Di.chm"
Name: "{group}\Uputstvo za korisnike"; Filename: "{app}\Manual.pdf"
Name: "{group}\Istorija izmena"; Filename: "{app}\History of changes.TXT"
Name: "{group}\Licenca"; Filename: "{app}\License.TXT"
Name: "{group}\Poznate greske"; Filename: "{app}\Known bugs.TXT"
Name: "{group}\{cm:UninstallProgram,Di recnik}"; Filename: "{uninstallexe}"
Name: "{userdesktop}\Di recnik"; Filename: "{app}\Di.exe"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\Di recnik"; Filename: "{app}\Di.exe"; Tasks: quicklaunchicon
[Run]
Filename: "{app}\Di.exe"; Description: "{cm:LaunchProgram,Di rečnik}"; Flags: nowait postinstall skipifsilent
Filename: "{app}\SPCHAPI.EXE"; Parameters: "/q"
Filename: "{app}\LHTTSENG.EXE"; Parameters: "/q"
Filename: "{app}\diie.exe"; Parameters: "{app}"
[UninstallDelete]
Type: filesandordirs; Name: "{app}\*.*"
Type: filesandordirs; Name: "{group}\*.*"
[Code]
// =========================================================================================================================
// GLOBAL VARIABLES
// =========================================================================================================================
// New EXE version
const THIS_VERSION = '{#AppVersion}';
// First EXE version with ability to be closed programmaticaly
const THE_FIRST_VER_WITH_AUTOMATIC_CLOSE = '1.0.0.56';
// previuos install dir
var PrevDir: String;
// previous group
var PrevGrp: String;
// is Overwrite ? ... because of skipping few pages ...
var Overwrite: Boolean;
// installed program version
var InstalledVer: String;
// =========================================================================================================================
// =========================================================================================================================
// DECODING THE APP VERSION FROM EXE
// =========================================================================================================================
// Decoding
procedure DecodeVersion( verstr: String; var verint: array of Integer );
var i,p: Integer; s: string;
begin
// initialize array
verint := [0,0,0,0];
i := 0;
while ( (Length(verstr) > 0) and (i < 4) ) do
begin
p := pos('.', verstr);
if p > 0 then
begin
if p = 1 then
s:= '0'
else
s:= Copy( verstr, 1, p - 1 );
verint[i] := StrToInt(s);
i := i + 1;
verstr := Copy( verstr, p+1, Length(verstr));
end
else
begin
verint[i] := StrToInt( verstr );
verstr := '';
end;
end;
end;
// Comparing: return -1 if ver1 < ver2, return 0 if ver1 = ver2, return 1 if ver1 > ver2
function CompareVersion( ver1, ver2: String ) : Integer;
var verint1, verint2: array of Integer;
i: integer;
begin
SetArrayLength( verint1, 4 );
DecodeVersion( ver1, verint1 );
SetArrayLength( verint2, 4 );
DecodeVersion( ver2, verint2 );
Result := 0; i := 0;
while ( (Result = 0) and ( i < 4 ) ) do
begin
if verint1[i] > verint2[i] then
Result := 1
else
if verint1[i] < verint2[i] then
Result := -1
else
Result := 0;
i := i + 1;
end;
end;
// =========================================================================================================================
// =========================================================================================================================
// GETTING PREVIOUS INSTALLATION DATA FROM REGISTRY
// =========================================================================================================================
// Get where the application was installed
function GetPathInstalled( InstallID: String ): String;
var sPrevPath: String;
begin
sPrevPath := '';
if not RegQueryStringValue( HKLM,
'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + InstallID + '_is1',
'Inno Setup: App Path',
sPrevPath ) then
RegQueryStringValue( HKCU,
'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + InstallID + '_is1',
'Inno Setup: App Path',
sPrevPath );
Result := sPrevPath;
end;
// Get the Group Name
function GetIconGroupName( InstallID: String ): String;
var sIconGroupName: String;
begin
sIconGroupName := '';
if not RegQueryStringValue( HKLM,
'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + InstallID + '_is1',
'Inno Setup: Icon Group',
sIconGroupName ) then
RegQueryStringValue( HKCU,
'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + InstallID + '_is1',
'Inno Setup: Icon Group',
sIconGroupName );
Result := sIconGroupName;
end;
// Is installed before
function IsInstalledBefore( InstallID : String ) : String;
begin
Result := GetPathInstalled( InstallID )
end;
// =========================================================================================================================
// =========================================================================================================================
// CONDITIONAL ASSIGNMENTS FOR THE [Setup] SECTION
// =========================================================================================================================
// Global previous directory
function GetPrevDir( s : String ) : String;
begin
if length( PrevDir ) = 0 then
Result := s
else
Result := PrevDir;
end;
// Global previous group
function GetPrevGrp( s : String ) : String;
begin
if length( PrevGrp ) = 0 then
Result := s
else
Result := PrevGrp;
end;
// Should set mutex to prevent from installing
function DetermineIfToSetMutex( s: String ) : String;
var vercomp : Integer;
var PreviousDir : String;
var VerInstalled : String;
begin
Result := 'fake_mutex';
// read the installation folder
PreviousDir := IsInstalledBefore( '{#SetupSetting("AppID")}' );
// This is because of the fact that I haven't set the AppID in the versions < 1.0.0.51
if ( PreviousDir = '' ) then
PreviousDir := IsInstalledBefore( '{#SetupSetting("AppName")}' );
if length( PreviousDir ) > 0 then
begin
// read the version of di.exe already installed
GetVersionNumbersString( PreviousDir + '\di.exe' , VerInstalled );
// compare versions
vercomp := CompareVersion( VerInstalled, THE_FIRST_VER_WITH_AUTOMATIC_CLOSE );
// version is smaller, so there is no mechanism to close the running app - keep mutex solution
if vercomp < 0 then
begin
Result := 'notdi';
end
end
end;
// =========================================================================================================================
// =========================================================================================================================
// CLOSING THE APP
// =========================================================================================================================
// Closing code
procedure QuitApp;
var h : integer;
begin
h := FindWindowByClassName('TDiMainForm');
SendMessage(h, 1024+1005, 0, 0 );
end;
// Closing app after Install button
procedure CurStepChanged(CurStep: TSetupStep);
begin
if ( CurStep = ssInstall ) then
begin
QuitApp;
Sleep(3000);
end
end;
// Closing app after OK button on Uninstall
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if ( CurUninstallStep = usUninstall ) then
begin
QuitApp;
Sleep(3000);
end
end;
// =========================================================================================================================
// =========================================================================================================================
// SKIPPING PAGES IF THE FOLDER EXISTS
// =========================================================================================================================
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := false
if Overwrite then
begin
if ( PageID = wpSelectDir ) then
Result := true
if ( PageID = wpSelectProgramGroup ) then
Result := true
if ( PageID = wpSelectTasks ) then
Result := true
end
end;
// *************************************************************************************************************************
// INITIALIZATION
// *************************************************************************************************************************
function InitializeSetup(): Boolean;
var vercomp, answ : Integer;
begin
// Pessimistic
Result := false;
// Pessimistic
Overwrite := false;
// Is app installed before -------------------------------------------------------------------------------------------
PrevDir := IsInstalledBefore( '{#SetupSetting("AppID")}' );
// If previous failed, ask again but with new argument
// (this is because of the fact that I haven't set the AppID in the versions < 1.0.0.51)
if ( PrevDir = '' ) then
PrevDir := IsInstalledBefore( '{#SetupSetting("AppName")}' );
// Set group name ----------------------------------------------------------------------------------------------------
PrevGrp := GetIconGroupName( '{#SetupSetting("AppID")}' );
// If previous failed, ask again but with new argument
// (this is because of the fact that I haven't set the AppID in the versions < 1.0.0.51)
if ( PrevGrp = '' ) then
PrevGrp := GetIconGroupName( '{#SetupSetting("AppName")}' );
if length( PrevDir ) > 0 then
begin
// It's an upgrade
Overwrite := true;
// read the version of MyProg.exe already installed
GetVersionNumbersString( PrevDir + '\di.exe' , InstalledVer );
// compare versions
vercomp := CompareVersion( InstalledVer, THIS_VERSION );
// version smaller
if vercomp < 0 then
begin
//if MsgBox( 'A previous version of Di dictionary is already installed.'#13
// 'It is recommended that you uninstall the existing version (Control Panel / Add Remove Programs) before running this setup.'#13#13
// 'If you still decide to overwrite the old version, you will not be able to chose the destination location and the Start menu folder.'#13#13
// 'Click OK to continue, or Cancel to abort.', mbInformation, MB_okcancel) = idok then
if MsgBox( 'Prethodna verzija Di rečnika je već instalirana.'#13
'Preporučuje se da deinstalirate prethodnu verziju (Control Panel/Add Remove Programs) pre nastavka instalacije.'#13
'Ako se ipak odlučite da instalirate preko stare verzije, nećete moći da birate odredišnu lokaciju i programsku grupu za Start meni.'#13#13
'Pritisnike OK za nastavak, ili Cancel da izađete.', mbInformation, MB_OKCANCEL ) = IDOK then
Result := true;
end;
// same version, ask what to do
if vercomp = 0 then
begin
answ := MsgBox( 'Utvrđeno je da je identična verzija programa ('+ InstalledVer +') već instalirana.'
+ #13#13 + 'Da li želite da ipak izvršite instalaciju?', mbConfirmation, MB_YESNO )
// If user answer is NO abort setup
Result := ( answ = IDYES );
end;
// version bigger, cannot upgrade with a smaller version
if vercomp > 0 then
begin
MsgBox('Pronađena je verzija Di rečnik, '+ InstalledVer +
' a Vi želite da instalirate verziju ' + THIS_VERSION
+ #13#13 + 'Instalacija je prekinuta. Ako ipak želite da instalirate ovu verziju, prethodno morate deinstalirati aktuelnu.', mbError, MB_OK );
Result := false;
end;
end
if Length ( PrevDir ) = 0 then
Result := true;
end;