#define LocalizedLanguageFile(Language = "") \ DirExists(RepoDir + "\licenses") && Language != "" \ ? ('; LicenseFile: "' + RepoDir + '\licenses\LICENSE-' + Language + '.txt"') \ : '; LicenseFile: "' + RepoDir + '\LICENSE.txt"' [Setup] AppId={#AppId} AppName={#NameLong} AppVerName={#NameVersion} AppPublisher=Microsoft Corporation AppPublisherURL=https://github.com/Microsoft/sqlopsstudio AppSupportURL=https://github.com/Microsoft/sqlopsstudio AppUpdatesURL=https://github.com/Microsoft/sqlopsstudio DefaultDirName={pf}\{#DirName} DefaultGroupName={#NameLong} AllowNoIcons=yes OutputDir={#OutputDir} OutputBaseFilename=SqlOpsStudioSetup Compression=lzma SolidCompression=yes AppMutex={code:GetAppMutex} SetupMutex={#AppMutex}setup WizardImageFile={#RepoDir}\resources\win32\inno-big.bmp WizardSmallImageFile={#RepoDir}\resources\win32\inno-small.bmp SetupIconFile={#RepoDir}\resources\win32\code.ico UninstallDisplayIcon={app}\{#ExeBasename}.exe ChangesEnvironment=true ChangesAssociations=true MinVersion=6.1.7600 SourceDir={#SourceDir} AppVersion={#Version} VersionInfoVersion={#RawVersion} ShowLanguageDialog=auto ArchitecturesAllowed={#ArchitecturesAllowed} ArchitecturesInstallIn64BitMode={#ArchitecturesInstallIn64BitMode} [Languages] Name: "english"; MessagesFile: "compiler:Default.isl,{#RepoDir}\build\win32\i18n\messages.en.isl" {#LocalizedLanguageFile} Name: "german"; MessagesFile: "compiler:Languages\German.isl,{#RepoDir}\build\win32\i18n\messages.de.isl" {#LocalizedLanguageFile("deu")} Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl,{#RepoDir}\build\win32\i18n\messages.es.isl" {#LocalizedLanguageFile("esp")} Name: "french"; MessagesFile: "compiler:Languages\French.isl,{#RepoDir}\build\win32\i18n\messages.fr.isl" {#LocalizedLanguageFile("fra")} Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl,{#RepoDir}\build\win32\i18n\messages.it.isl" {#LocalizedLanguageFile("ita")} Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl,{#RepoDir}\build\win32\i18n\messages.ja.isl" {#LocalizedLanguageFile("jpn")} Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl,{#RepoDir}\build\win32\i18n\messages.ru.isl" {#LocalizedLanguageFile("rus")} Name: "korean"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.ko.isl,{#RepoDir}\build\win32\i18n\messages.ko.isl" {#LocalizedLanguageFile("kor")} Name: "simplifiedChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh-cn.isl,{#RepoDir}\build\win32\i18n\messages.zh-cn.isl" {#LocalizedLanguageFile("chs")} Name: "traditionalChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh-tw.isl,{#RepoDir}\build\win32\i18n\messages.zh-tw.isl" {#LocalizedLanguageFile("cht")} [InstallDelete] Type: filesandordirs; Name: "{app}\resources\app\out"; Check: IsNotUpdate Type: filesandordirs; Name: "{app}\resources\app\plugins"; Check: IsNotUpdate Type: filesandordirs; Name: "{app}\resources\app\extensions"; Check: IsNotUpdate Type: filesandordirs; Name: "{app}\resources\app\node_modules"; Check: IsNotUpdate Type: filesandordirs; Name: "{app}\resources\app\node_modules.asar.unpacked"; Check: IsNotUpdate Type: files; Name: "{app}\resources\app\node_modules.asar"; Check: IsNotUpdate Type: files; Name: "{app}\resources\app\Credits_45.0.2454.85.html"; Check: IsNotUpdate [UninstallDelete] Type: filesandordirs; Name: "{app}\_" [Tasks] Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1 Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}" Name: "runcode"; Description: "{cm:RunAfter,{#NameShort}}"; GroupDescription: "{cm:Other}"; Check: WizardSilent [Files] Source: "*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs [Icons] Name: "{group}\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; AppUserModelID: "{#AppUserId}" Name: "{commondesktop}\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; AppUserModelID: "{#AppUserId}" Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; Tasks: quicklaunchicon; AppUserModelID: "{#AppUserId}" [Run] Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Tasks: runcode; Flags: nowait postinstall; Check: ShouldRunAfterUpdate Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Flags: nowait postinstall; Check: WizardNotSilent [Registry] Root: HKCR; Subkey: "{#RegValueName}SourceFile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,{#NameLong}}"; Flags: uninsdeletekey Root: HKCR; Subkey: "{#RegValueName}SourceFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\code_file.ico" Root: HKCR; Subkey: "{#RegValueName}SourceFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1""" Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{app}\bin"; Tasks: addtopath; Check: NeedsAddPath(ExpandConstant('{app}\bin')) [Code] // Don't allow installing conflicting architectures function InitializeSetup(): Boolean; var RegKey: String; ThisArch: String; AltArch: String; begin Result := True; if IsWin64 then begin RegKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + copy('{#IncompatibleAppId}', 2, 38) + '_is1'; if '{#Arch}' = 'ia32' then begin Result := not RegKeyExists(HKLM64, RegKey); ThisArch := '32'; AltArch := '64'; end else begin Result := not RegKeyExists(HKLM32, RegKey); ThisArch := '64'; AltArch := '32'; end; if not Result then begin MsgBox('Please uninstall the ' + AltArch + '-bit version of {#NameShort} before installing this ' + ThisArch + '-bit version.', mbInformation, MB_OK); end; end; end; function WizardNotSilent(): Boolean; begin Result := not WizardSilent(); end; // Updates function IsBackgroundUpdate(): Boolean; begin Result := ExpandConstant('{param:update|false}') <> 'false'; end; function IsNotUpdate(): Boolean; begin Result := not IsBackgroundUpdate(); end; // SqlOps will create a flag file before the update starts (/update=C:\foo\bar) // - if the file exists at this point, the user quit SqlOps before the update finished, so don't start SqlOps after update // - otherwise, the user has accepted to apply the update and SqlOps should start function LockFileExists(): Boolean; begin Result := FileExists(ExpandConstant('{param:update}')) end; function ShouldRunAfterUpdate(): Boolean; begin if IsBackgroundUpdate() then Result := not LockFileExists() else Result := True; end; function GetAppMutex(Value: string): string; begin if IsBackgroundUpdate() then Result := '' else Result := '{#AppMutex}'; end; function GetDestDir(Value: string): string; begin if IsBackgroundUpdate() then Result := ExpandConstant('{app}\_') else Result := ExpandConstant('{app}'); end; function BoolToStr(Value: Boolean): String; begin if Value then Result := 'true' else Result := 'false'; end; procedure CurStepChanged(CurStep: TSetupStep); var UpdateResultCode: Integer; begin if IsBackgroundUpdate() and (CurStep = ssPostInstall) then begin CreateMutex('{#AppMutex}-ready'); while (CheckForMutexes('{#AppMutex}')) do begin Log('Application is still running, waiting'); Sleep(1000); end; Exec(ExpandConstant('{app}\tools\inno_updater.exe'), ExpandConstant('"{app}\{#ExeBasename}.exe" ' + BoolToStr(LockFileExists())), '', SW_SHOW, ewWaitUntilTerminated, UpdateResultCode); end; end; // http://stackoverflow.com/a/23838239/261019 procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String); var i, p: Integer; begin i := 0; repeat SetArrayLength(Dest, i+1); p := Pos(Separator,Text); if p > 0 then begin Dest[i] := Copy(Text, 1, p-1); Text := Copy(Text, p + Length(Separator), Length(Text)); i := i + 1; end else begin Dest[i] := Text; Text := ''; end; until Length(Text)=0; end; function NeedsAddPath(Param: string): boolean; var OrigPath: string; begin if not RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', OrigPath) then begin Result := True; exit; end; Result := Pos(';' + Param + ';', ';' + OrigPath + ';') = 0; end; procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); var Path: string; CarbonPath: string; Parts: TArrayOfString; NewPath: string; i: Integer; begin if not CurUninstallStep = usUninstall then begin exit; end; if not RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', Path) then begin exit; end; NewPath := ''; CarbonPath := ExpandConstant('{app}\bin') Explode(Parts, Path, ';'); for i:=0 to GetArrayLength(Parts)-1 do begin if CompareText(Parts[i], CarbonPath) <> 0 then begin NewPath := NewPath + Parts[i]; if i < GetArrayLength(Parts) - 1 then begin NewPath := NewPath + ';'; end; end; end; RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', NewPath); end;