diff --git a/Greenshot/tools/innosetup/Builtins.iss b/Greenshot/tools/innosetup/Builtins.iss new file mode 100644 index 000000000..617939944 --- /dev/null +++ b/Greenshot/tools/innosetup/Builtins.iss @@ -0,0 +1,352 @@ +; BEGIN BUILTINS.ISS +// +// Inno Setup Preprocessor 5 +// +// Copyright (C) 2001-2004 Alex Yackimoff. All Rights Reserved. +// Portions by Martijn Laan. +// http://ispp.sourceforge.net +// +// Inno Setup (C) 1997-2009 Jordan Russell. All Rights Reserved. +// Portions by Martijn Laan. +// +// $Id: Builtins.iss,v 1.10 2009/08/03 14:18:14 mlaan Exp $ +// +#if defined(ISPP_INVOKED) && !defined(_BUILTINS_ISS_) +// +#if PREPROCVER < 0x01000000 +# error Inno Setup Preprocessor version is outdated +#endif +// +#define _BUILTINS_ISS_ +// +// =========================================================================== +// +// Default states for options. +// +//#pragma parseroption -b+ ; short circuit boolean evaluation: on +//#pragma parseroption -m- ; short circuit multiplication evaluation (0 * A will not eval A): off +//#pragma parseroption -p+ ; string literals without escape sequences: on +//#pragma parseroption -u- ; allow undeclared identifiers: off +//#pragma option -c+ ; pass script to the compiler: on +//#pragma option -e- ; emit empty lines to translation: off +//#pragma option -v- ; verbose mode: off +// +// --------------------------------------------------------------------------- +// +// Verbose levels: +// 0 - #include and #file acknowledgements +// 1 - information about any temp files created by #file +// 2 - #insert and #append acknowledgements +// 3 - reserved +// 4 - #dim, #define and #undef acknowledgements +// 5 - reserved +// 6 - conditional inclusion acknowledgements +// 7 - reserved +// 8 - show strings emitted with #emit directive +// 9 - macro and functions successfull call acknowledgements +//10 - Local macro array allocation acknowledgements +// +//#pragma verboselevel 0 +// +#ifndef __POPT_P__ +# define private CStrings +# pragma parseroption -p+ +#endif +// +#pragma spansymbol "\" +// +#define True 1 +#define False 0 +#define Yes True +#define No False +// +#define MaxInt 0x7FFFFFFFL +#define MinInt 0x80000000L +// +#define NULL +#define void +// +// TypeOf constants +// +#define TYPE_ERROR 0 +#define TYPE_NULL 1 +#define TYPE_INTEGER 2 +#define TYPE_STRING 3 +#define TYPE_MACRO 4 +#define TYPE_FUNC 5 +#define TYPE_ARRAY 6 +// +// Helper macro to find out the type of an array element or expression. TypeOf +// standard function only allows identifier as its parameter. Use this macro +// to convert an expression to identifier. +// +#define TypeOf2(any Expr) TypeOf(Expr) +// +// ReadReg constants +// +#define HKEY_CLASSES_ROOT 0x80000000UL +#define HKEY_CURRENT_USER 0x80000001UL +#define HKEY_LOCAL_MACHINE 0x80000002UL +#define HKEY_USERS 0x80000003UL +// +#define HKCR HKEY_CLASSES_ROOT +#define HKCU HKEY_CURRENT_USER +#define HKLM HKEY_LOCAL_MACHINE +#define HKU HKEY_USERS +// +// Exec constants +// +#define SW_HIDE 0 +#define SW_SHOWNORMAL 1 +#define SW_NORMAL 1 +#define SW_SHOWMINIMIZED 2 +#define SW_SHOWMAXIMIZED 3 +#define SW_MAXIMIZE 3 +#define SW_SHOWNOACTIVATE 4 +#define SW_SHOW 5 +#define SW_MINIMIZE 6 +#define SW_SHOWMINNOACTIVE 7 +#define SW_SHOWNA 8 +#define SW_RESTORE 9 +#define SW_SHOWDEFAULT 10 +#define SW_MAX 10 +// +// Find constants +// +#define FIND_MATCH 0x00 +#define FIND_BEGINS 0x01 +#define FIND_ENDS 0x02 +#define FIND_CONTAINS 0x03 +#define FIND_CASESENSITIVE 0x04 +#define FIND_SENSITIVE FIND_CASESENSITIVE +#define FIND_AND 0x00 +#define FIND_OR 0x08 +#define FIND_NOT 0x10 +#define FIND_TRIM 0x20 +// +// FindFirst constants +// +#define faReadOnly 0x00000001 +#define faHidden 0x00000002 +#define faSysFile 0x00000004 +#define faVolumeID 0x00000008 +#define faDirectory 0x00000010 +#define faArchive 0x00000020 +#define faSymLink 0x00000040 +#define faAnyFile 0x0000003F +// +// GetStringFileInfo standard names +// +#define COMPANY_NAME "CompanyName" +#define FILE_DESCRIPTION "FileDescription" +#define FILE_VERSION "FileVersion" +#define INTERNAL_NAME "InternalName" +#define LEGAL_COPYRIGHT "LegalCopyright" +#define ORIGINAL_FILENAME "OriginalFilename" +#define PRODUCT_NAME "ProductName" +#define PRODUCT_VERSION "ProductVersion" +// +// GetStringFileInfo helpers +// +#define GetFileCompany(str FileName) GetStringFileInfo(FileName, COMPANY_NAME) +#define GetFileCopyright(str FileName) GetStringFileInfo(FileName, LEGAL_COPYRIGHT) +#define GetFileDescription(str FileName) GetStringFileInfo(FileName, FILE_DESCRIPTION) +#define GetFileProductVersion(str FileName) GetStringFileInfo(FileName, PRODUCT_VERSION) +#define GetFileVersionString(str FileName) GetStringFileInfo(FileName, FILE_VERSION) +// +// ParseVersion +// +// Macro internally calls GetFileVersion function and parses string returned +// by that function (in form "0.0.0.0"). All four version elements are stored +// in by-reference parameters Major, Minor, Rev, and Build. Macro returns +// string returned by GetFileVersion. +// +#define DeleteToFirstPeriod(str *S) \ + Local[1] = Copy(S, 1, (Local[0] = Pos(".", S)) - 1), \ + S = Copy(S, Local[0] + 1), \ + Local[1] +// +#define ParseVersion(str FileName, *Major, *Minor, *Rev, *Build) \ + Local[1] = Local[0] = GetFileVersion(FileName), \ + Local[1] == "" ? "" : ( \ + Major = Int(DeleteToFirstPeriod(Local[1])), \ + Minor = Int(DeleteToFirstPeriod(Local[1])), \ + Rev = Int(DeleteToFirstPeriod(Local[1])), \ + Build = Int(Local[1]), \ + Local[0]) +// +// EncodeVer +// +// Encodes given four version elements to a 32 bit integer number (8 bits for +// each element, i.e. elements must be within 0...255 range). +// +#define EncodeVer(int Major, int Minor, int Revision = 0, int Build = -1) \ + Major << 24 | (Minor & 0xFF) << 16 | (Revision & 0xFF) << 8 | (Build >= 0 ? Build & 0xFF : 0) +// +// DecodeVer +// +// Decodes given 32 bit integer encoded version to its string representation, +// Digits parameter indicates how many elements to show (if the fourth element +// is 0, it won't be shown anyway). +// +#define DecodeVer(int Ver, int Digits = 3) \ + Str(Ver >> 0x18 & 0xFF) + (Digits > 1 ? "." : "") + \ + (Digits > 1 ? \ + Str(Ver >> 0x10 & 0xFF) + (Digits > 2 ? "." : "") : "") + \ + (Digits > 2 ? \ + Str(Ver >> 0x08 & 0xFF) + (Digits > 3 && (Local = Ver & 0xFF) ? "." : "") : "") + \ + (Digits > 3 && Local ? \ + Str(Ver & 0xFF) : "") +// +// FindSection +// +// Returns index of the line following the header of the section. This macro +// is intended to be used with #insert directive. +// +#define FindSection(str Section = "Files") \ + Find(0, "[" + Section + "]", FIND_MATCH | FIND_TRIM) + 1 +// +// FindSectionEnd +// +// Returns index of the line following last entry of the section. This macro +// is intended to be used with #insert directive. +// +#if VER >= 0x03000000 +# define FindNextSection(int Line) \ + Find(Line, "[", FIND_BEGINS | FIND_TRIM, "]", FIND_ENDS | FIND_AND) +# define FindSectionEnd(str Section = "Files") \ + FindNextSection(FindSection(Section)) +#else +# define FindSectionEnd(str Section = "Files") \ + FindSection(Section) + EntryCount(Section) +#endif +// +// FindCode +// +// Returns index of the line (of translation) following either [Code] section +// header, or "program" keyword, if any. +// +#define FindCode() \ + Local[1] = FindSection("Code"), \ + Local[0] = Find(Local[1] - 1, "program", FIND_BEGINS, ";", FIND_ENDS | FIND_AND), \ + (Local[0] < 0 ? Local[1] : Local[0] + 1) +// +// ExtractFilePath +// +// Returns directory portion of the given filename without backslash (unless +// it is a root directory). If PathName doesn't contain directory portion, +// the result is an empty string. +// +#define ExtractFilePath(str PathName) \ + (Local[0] = \ + !(Local[1] = RPos("\", PathName)) ? \ + "" : \ + Copy(PathName, 1, Local[1] - 1)), \ + Local[0] + \ + ((Local[2] = Len(Local[0])) == 2 && Copy(Local[0], Local[2]) == ":" ? \ + "\" : \ + "") +#define ExtractFileDir(str PathName) \ + RemoveBackslash(ExtractFilePath(PathName)) + +#define ExtractFileExt(str PathName) \ + Local[0] = RPos(".", PathName), \ + Copy(PathName, Local[0] + 1) +// +// ExtractFileName +// +// Returns name portion of the given filename. If PathName ends with +// a backslash, the result is an empty string. +// +#define ExtractFileName(str PathName) \ + !(Local[0] = RPos("\", PathName)) ? \ + PathName : \ + Copy(PathName, Local[0] + 1) +// +// ChangeFileExt +// +// Changes extension in FileName with NewExt. NewExt must not contain +// period. +// +#define ChangeFileExt(str FileName, str NewExt) \ + !(Local[0] = RPos(".", FileName)) ? \ + FileName + "." + NewExt : \ + Copy(FileName, 1, Local[0]) + NewExt +// +// AddBackslash +// +// Adds a backslash to the string, if it's not already there. +// +#define AddBackslash(str S) \ + Copy(S, Len(S)) == "\" ? S : S + "\" +// +// RemoveBackslash +// +// Removes trailing backslash from the string unless the string points to +// a root directory. +// +#define RemoveBackslash(str S) \ + Local[0] = Len(S), \ + Local[0] > 0 ? \ + Copy(S, Local[0]) == "\" ? \ + (Local[0] == 3 && Copy(S, 2, 1) == ":" ? \ + S : \ + Copy(S, 1, Local[0] - 1)) : \ + S : \ + "" +// +// Delete +// +// Deletes specified number of characters beginning with Index from S. S is +// passed by reference (therefore is modified). Acts like Delete function in +// Delphi (from System unit). +// +#define Delete(str *S, int Index, int Count = MaxInt) \ + S = Copy(S, 1, Index - 1) + Copy(S, Index + Count) +// +// Insert +// +// Inserts specified Substr at Index'th character into S. S is passed by +// reference (therefore is modified). +// +#define Insert(str *S, int Index, str Substr) \ + Index > Len(S) + 1 ? \ + S : \ + S = Copy(S, 1, Index - 1) + SubStr + Copy(S, Index) +// +// YesNo, IsDirSet +// +// Returns nonzero value if given string is "yes", "true" or "1". Intended to +// be used with SetupSetting function. This macro replaces YesNo function +// available in previous releases. +// +#define YesNo(str S) \ + (S = LowerCase(S)) == "yes" || S == "true" || S == "1" +// +#define IsDirSet(str SetupDirective) \ + YesNo(SetupSetting(SetupDirective)) +// +// +#define Power(int X, int P = 2) \ + !P ? 1 : X * Power(X, P - 1) +// +#define Min(int A, int B, int C = MaxInt) \ + A < B ? A < C ? Int(A) : Int(C) : Int(B) +// +#define Max(int A, int B, int C = MinInt) \ + A > B ? A > C ? Int(A) : Int(C) : Int(B) +// + +; The following message can be overriden in ISS script. +; It is not required by ISPP license agreement, but it would be appreciated +; if you do not remove this note. + +[Messages] +AboutSetupNote=Inno Setup Preprocessor home page:%nhttp://ispp.sourceforge.net/ +[/Messages] +#ifdef CStrings +# pragma parseroption -p- +#endif +#endif +; END BUILTINS.ISS + diff --git a/Greenshot/tools/innosetup/Compil32.exe b/Greenshot/tools/innosetup/Compil32.exe index eed01a64c..07c4f826a 100644 Binary files a/Greenshot/tools/innosetup/Compil32.exe and b/Greenshot/tools/innosetup/Compil32.exe differ diff --git a/Greenshot/tools/innosetup/Examples/64Bit.iss b/Greenshot/tools/innosetup/Examples/64Bit.iss new file mode 100644 index 000000000..824fdaba5 --- /dev/null +++ b/Greenshot/tools/innosetup/Examples/64Bit.iss @@ -0,0 +1,32 @@ +; -- 64Bit.iss -- +; Demonstrates installation of a program built for the x64 (a.k.a. AMD64) +; architecture. +; To successfully run this installation and the program it installs, +; you must have the "x64" edition of Windows XP or Windows Server 2003. + +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING .ISS SCRIPT FILES! + +[Setup] +AppName=My Program +AppVersion=1.5 +DefaultDirName={pf}\My Program +DefaultGroupName=My Program +UninstallDisplayIcon={app}\MyProg.exe +Compression=lzma2 +SolidCompression=yes +OutputDir=userdocs:Inno Setup Examples Output +; "ArchitecturesAllowed=x64" specifies that Setup cannot run on +; anything but x64. +ArchitecturesAllowed=x64 +; "ArchitecturesInstallIn64BitMode=x64" requests that the install be +; done in "64-bit mode" on x64, meaning it should use the native +; 64-bit Program Files directory and the 64-bit view of the registry. +ArchitecturesInstallIn64BitMode=x64 + +[Files] +Source: "MyProg-x64.exe"; DestDir: "{app}"; DestName: "MyProg.exe" +Source: "MyProg.chm"; DestDir: "{app}" +Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme + +[Icons] +Name: "{group}\My Program"; Filename: "{app}\MyProg.exe" diff --git a/Greenshot/tools/innosetup/Examples/64BitThreeArch.iss b/Greenshot/tools/innosetup/Examples/64BitThreeArch.iss new file mode 100644 index 000000000..59bee0fee --- /dev/null +++ b/Greenshot/tools/innosetup/Examples/64BitThreeArch.iss @@ -0,0 +1,48 @@ +; -- 64BitThreeArch.iss -- +; Demonstrates how to install a program built for three different +; architectures (x86, x64, Itanium) using a single installer. + +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING .ISS SCRIPT FILES! + +[Setup] +AppName=My Program +AppVersion=1.5 +DefaultDirName={pf}\My Program +DefaultGroupName=My Program +UninstallDisplayIcon={app}\MyProg.exe +Compression=lzma2 +SolidCompression=yes +OutputDir=userdocs:Inno Setup Examples Output +; "ArchitecturesInstallIn64BitMode=x64 ia64" requests that the install +; be done in "64-bit mode" on x64 & Itanium, meaning it should use the +; native 64-bit Program Files directory and the 64-bit view of the +; registry. On all other architectures it will install in "32-bit mode". +ArchitecturesInstallIn64BitMode=x64 ia64 + +[Files] +; Install MyProg-x64.exe if running on x64, MyProg-IA64.exe if +; running on Itanium, MyProg.exe otherwise. +Source: "MyProg-x64.exe"; DestDir: "{app}"; DestName: "MyProg.exe"; Check: IsX64 +Source: "MyProg-IA64.exe"; DestDir: "{app}"; DestName: "MyProg.exe"; Check: IsIA64 +Source: "MyProg.exe"; DestDir: "{app}"; Check: IsOtherArch +Source: "MyProg.chm"; DestDir: "{app}" +Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme + +[Icons] +Name: "{group}\My Program"; Filename: "{app}\MyProg.exe" + +[Code] +function IsX64: Boolean; +begin + Result := Is64BitInstallMode and (ProcessorArchitecture = paX64); +end; + +function IsIA64: Boolean; +begin + Result := Is64BitInstallMode and (ProcessorArchitecture = paIA64); +end; + +function IsOtherArch: Boolean; +begin + Result := not IsX64 and not IsIA64; +end; diff --git a/Greenshot/tools/innosetup/Examples/64BitTwoArch.iss b/Greenshot/tools/innosetup/Examples/64BitTwoArch.iss new file mode 100644 index 000000000..30606a802 --- /dev/null +++ b/Greenshot/tools/innosetup/Examples/64BitTwoArch.iss @@ -0,0 +1,34 @@ +; -- 64BitTwoArch.iss -- +; Demonstrates how to install a program built for two different +; architectures (x86 and x64) using a single installer. + +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING .ISS SCRIPT FILES! + +[Setup] +AppName=My Program +AppVersion=1.5 +DefaultDirName={pf}\My Program +DefaultGroupName=My Program +UninstallDisplayIcon={app}\MyProg.exe +Compression=lzma2 +SolidCompression=yes +OutputDir=userdocs:Inno Setup Examples Output +; "ArchitecturesInstallIn64BitMode=x64" requests that the install be +; done in "64-bit mode" on x64, meaning it should use the native +; 64-bit Program Files directory and the 64-bit view of the registry. +; On all other architectures it will install in "32-bit mode". +ArchitecturesInstallIn64BitMode=x64 +; Note: We don't set ProcessorsAllowed because we want this +; installation to run on all architectures (including Itanium, +; since it's capable of running 32-bit code too). + +[Files] +; Install MyProg-x64.exe if running in 64-bit mode (x64; see above), +; MyProg.exe otherwise. +Source: "MyProg-x64.exe"; DestDir: "{app}"; DestName: "MyProg.exe"; Check: Is64BitInstallMode +Source: "MyProg.exe"; DestDir: "{app}"; Check: not Is64BitInstallMode +Source: "MyProg.chm"; DestDir: "{app}" +Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme + +[Icons] +Name: "{group}\My Program"; Filename: "{app}\MyProg.exe" diff --git a/Greenshot/tools/innosetup/Examples/CodeAutomation.iss b/Greenshot/tools/innosetup/Examples/CodeAutomation.iss new file mode 100644 index 000000000..26a21a4e7 --- /dev/null +++ b/Greenshot/tools/innosetup/Examples/CodeAutomation.iss @@ -0,0 +1,310 @@ +; -- CodeAutomation.iss -- +; +; This script shows how to use IDispatch based COM Automation objects. + +[Setup] +AppName=My Program +AppVersion=1.5 +CreateAppDir=no +DisableProgramGroupPage=yes +DefaultGroupName=My Program +UninstallDisplayIcon={app}\MyProg.exe +OutputDir=userdocs:Inno Setup Examples Output + +[Code] + +{--- SQLDMO ---} + +const + SQLServerName = 'localhost'; + SQLDMOGrowth_MB = 0; + +procedure SQLDMOButtonOnClick(Sender: TObject); +var + SQLServer, Database, DBFile, LogFile: Variant; + IDColumn, NameColumn, Table: Variant; +begin + if MsgBox('Setup will now connect to Microsoft SQL Server ''' + SQLServerName + ''' via a trusted connection and create a database. Do you want to continue?', mbInformation, mb_YesNo) = idNo then + Exit; + + { Create the main SQLDMO COM Automation object } + + try + SQLServer := CreateOleObject('SQLDMO.SQLServer'); + except + RaiseException('Please install Microsoft SQL server connectivity tools first.'#13#13'(Error ''' + GetExceptionMessage + ''' occurred)'); + end; + + { Connect to the Microsoft SQL Server } + + SQLServer.LoginSecure := True; + SQLServer.Connect(SQLServerName); + + MsgBox('Connected to Microsoft SQL Server ''' + SQLServerName + '''.', mbInformation, mb_Ok); + + { Setup a database } + + Database := CreateOleObject('SQLDMO.Database'); + Database.Name := 'Inno Setup'; + + DBFile := CreateOleObject('SQLDMO.DBFile'); + DBFile.Name := 'ISData1'; + DBFile.PhysicalName := 'c:\program files\microsoft sql server\mssql\data\IS.mdf'; + DBFile.PrimaryFile := True; + DBFile.FileGrowthType := SQLDMOGrowth_MB; + DBFile.FileGrowth := 1; + + Database.FileGroups.Item('PRIMARY').DBFiles.Add(DBFile); + + LogFile := CreateOleObject('SQLDMO.LogFile'); + LogFile.Name := 'ISLog1'; + LogFile.PhysicalName := 'c:\program files\microsoft sql server\mssql\data\IS.ldf'; + + Database.TransactionLog.LogFiles.Add(LogFile); + + { Add the database } + + SQLServer.Databases.Add(Database); + + MsgBox('Added database ''' + Database.Name + '''.', mbInformation, mb_Ok); + + { Setup some columns } + + IDColumn := CreateOleObject('SQLDMO.Column'); + IDColumn.Name := 'id'; + IDColumn.Datatype := 'int'; + IDColumn.Identity := True; + IDColumn.IdentityIncrement := 1; + IDColumn.IdentitySeed := 1; + IDColumn.AllowNulls := False; + + NameColumn := CreateOleObject('SQLDMO.Column'); + NameColumn.Name := 'name'; + NameColumn.Datatype := 'varchar'; + NameColumn.Length := '64'; + NameColumn.AllowNulls := False; + + { Setup a table } + + Table := CreateOleObject('SQLDMO.Table'); + Table.Name := 'authors'; + Table.FileGroup := 'PRIMARY'; + + { Add the columns and the table } + + Table.Columns.Add(IDColumn); + Table.Columns.Add(NameColumn); + + Database.Tables.Add(Table); + + MsgBox('Added table ''' + Table.Name + '''.', mbInformation, mb_Ok); +end; + +{--- IIS ---} + +const + IISServerName = 'localhost'; + IISServerNumber = '1'; + IISURL = 'http://127.0.0.1'; + +procedure IISButtonOnClick(Sender: TObject); +var + IIS, WebSite, WebServer, WebRoot, VDir: Variant; + ErrorCode: Integer; +begin + if MsgBox('Setup will now connect to Microsoft IIS Server ''' + IISServerName + ''' and create a virtual directory. Do you want to continue?', mbInformation, mb_YesNo) = idNo then + Exit; + + { Create the main IIS COM Automation object } + + try + IIS := CreateOleObject('IISNamespace'); + except + RaiseException('Please install Microsoft IIS first.'#13#13'(Error ''' + GetExceptionMessage + ''' occurred)'); + end; + + { Connect to the IIS server } + + WebSite := IIS.GetObject('IIsWebService', IISServerName + '/w3svc'); + WebServer := WebSite.GetObject('IIsWebServer', IISServerNumber); + WebRoot := WebServer.GetObject('IIsWebVirtualDir', 'Root'); + + { (Re)create a virtual dir } + + try + WebRoot.Delete('IIsWebVirtualDir', 'innosetup'); + WebRoot.SetInfo(); + except + end; + + VDir := WebRoot.Create('IIsWebVirtualDir', 'innosetup'); + VDir.AccessRead := True; + VDir.AppFriendlyName := 'Inno Setup'; + VDir.Path := 'C:\inetpub\innosetup'; + VDir.AppCreate(True); + VDir.SetInfo(); + + MsgBox('Created virtual directory ''' + VDir.Path + '''.', mbInformation, mb_Ok); + + { Write some html and display it } + + if MsgBox('Setup will now write some HTML and display the virtual directory. Do you want to continue?', mbInformation, mb_YesNo) = idNo then + Exit; + + ForceDirectories(VDir.Path); + SaveStringToFile(VDir.Path + '/index.htm', '
Inno Setup rocks!', False); + if not ShellExec('open', IISURL + '/innosetup/index.htm', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode) then + MsgBox('Can''t display the created virtual directory: ''' + SysErrorMessage(ErrorCode) + '''.', mbError, mb_Ok); +end; + +{--- MSXML ---} + +const + XMLURL = 'http://cvs.jrsoftware.org/view/*checkout*/ishelp/isxfunc.xml'; + XMLFileName = 'isxfunc.xml'; + XMLFileName2 = 'isxfuncmodified.xml'; + +procedure MSXMLButtonOnClick(Sender: TObject); +var + XMLHTTP, XMLDoc, NewNode, RootNode: Variant; + Path: String; +begin + if MsgBox('Setup will now use MSXML to download XML file ''' + XMLURL + ''' and save it to disk.'#13#13'Setup will then load, modify and save this XML file. Do you want to continue?', mbInformation, mb_YesNo) = idNo then + Exit; + + { Create the main MSXML COM Automation object } + + try + XMLHTTP := CreateOleObject('MSXML2.ServerXMLHTTP'); + except + RaiseException('Please install MSXML first.'#13#13'(Error ''' + GetExceptionMessage + ''' occurred)'); + end; + + { Download the XML file } + + XMLHTTP.Open('GET', XMLURL, False); + XMLHTTP.Send(); + + Path := ExpandConstant('{src}\'); + XMLHTTP.responseXML.Save(Path + XMLFileName); + + MsgBox('Downloaded the XML file and saved it as ''' + XMLFileName + '''.', mbInformation, mb_Ok); + + { Load the XML File } + + XMLDoc := CreateOleObject('MSXML2.DOMDocument'); + XMLDoc.async := False; + XMLDoc.resolveExternals := False; + XMLDoc.load(Path + XMLFileName); + if XMLDoc.parseError.errorCode <> 0 then + RaiseException('Error on line ' + IntToStr(XMLDoc.parseError.line) + ', position ' + IntToStr(XMLDoc.parseError.linepos) + ': ' + XMLDoc.parseError.reason); + + MsgBox('Loaded the XML file.', mbInformation, mb_Ok); + + { Modify the XML document } + + NewNode := XMLDoc.createElement('isxdemo'); + RootNode := XMLDoc.documentElement; + RootNode.appendChild(NewNode); + RootNode.lastChild.text := 'Hello, World'; + + { Save the XML document } + + XMLDoc.Save(Path + XMLFileName2); + + MsgBox('Saved the modified XML as ''' + XMLFileName2 + '''.', mbInformation, mb_Ok); +end; + + +{--- Word ---} + +procedure WordButtonOnClick(Sender: TObject); +var + Word: Variant; +begin + if MsgBox('Setup will now check whether Microsoft Word is running. Do you want to continue?', mbInformation, mb_YesNo) = idNo then + Exit; + + { Try to get an active Word COM Automation object } + + try + Word := GetActiveOleObject('Word.Application'); + except + end; + + if VarIsEmpty(Word) then + MsgBox('Microsoft Word is not running.', mbInformation, mb_Ok) + else + MsgBox('Microsoft Word is running.', mbInformation, mb_Ok) +end; + +{--- Windows Firewall ---} + +const + NET_FW_IP_VERSION_ANY = 2; + NET_FW_SCOPE_ALL = 0; + +procedure FirewallButtonOnClick(Sender: TObject); +var + Firewall, Application: Variant; +begin + if MsgBox('Setup will now add itself to Windows Firewall as an authorized application for the current profile (' + GetUserNameString + '). Do you want to continue?', mbInformation, mb_YesNo) = idNo then + Exit; + + { Create the main Windows Firewall COM Automation object } + + try + Firewall := CreateOleObject('HNetCfg.FwMgr'); + except + RaiseException('Please install Windows Firewall first.'#13#13'(Error ''' + GetExceptionMessage + ''' occurred)'); + end; + + { Add the authorization } + + Application := CreateOleObject('HNetCfg.FwAuthorizedApplication'); + Application.Name := 'Setup'; + Application.IPVersion := NET_FW_IP_VERSION_ANY; + Application.ProcessImageFileName := ExpandConstant('{srcexe}'); + Application.Scope := NET_FW_SCOPE_ALL; + Application.Enabled := True; + + Firewall.LocalPolicy.CurrentProfile.AuthorizedApplications.Add(Application); + + MsgBox('Setup is now an authorized application for the current profile', mbInformation, mb_Ok); +end; + +{---} + +procedure CreateButton(ALeft, ATop: Integer; ACaption: String; ANotifyEvent: TNotifyEvent); +begin + with TButton.Create(WizardForm) do begin + Left := ALeft; + Top := ATop; + Width := WizardForm.CancelButton.Width; + Height := WizardForm.CancelButton.Height; + Caption := ACaption; + OnClick := ANotifyEvent; + Parent := WizardForm.WelcomePage; + end; +end; + +procedure InitializeWizard(); +var + Left, LeftInc, Top, TopInc: Integer; +begin + Left := WizardForm.WelcomeLabel2.Left; + LeftInc := WizardForm.CancelButton.Width + ScaleX(8); + TopInc := WizardForm.CancelButton.Height + ScaleY(8); + Top := WizardForm.WelcomeLabel2.Top + WizardForm.WelcomeLabel2.Height - 4*TopInc; + + CreateButton(Left, Top, '&SQLDMO...', @SQLDMOButtonOnClick); + CreateButton(Left + LeftInc, Top, '&Firewall...', @FirewallButtonOnClick); + Top := Top + TopInc; + CreateButton(Left, Top, '&IIS...', @IISButtonOnClick); + Top := Top + TopInc; + CreateButton(Left, Top, '&MSXML...', @MSXMLButtonOnClick); + Top := Top + TopInc; + CreateButton(Left, Top, '&Word...', @WordButtonOnClick); +end; + + diff --git a/Greenshot/tools/innosetup/Examples/CodeAutomation2.iss b/Greenshot/tools/innosetup/Examples/CodeAutomation2.iss new file mode 100644 index 000000000..c6f87005f --- /dev/null +++ b/Greenshot/tools/innosetup/Examples/CodeAutomation2.iss @@ -0,0 +1,298 @@ +; -- CodeAutomation2.iss -- +; +; This script shows how to use IUnknown based COM Automation objects. +; +; REQUIRES UNICODE INNO SETUP! +; +; Note: some unneeded interface functions which had special types have been replaced +; by dummies to avoid having to define those types. Do not remove these dummies as +; that would change the function indices which is bad. Also, not all function +; protoypes have been tested, only those used by this example. + +[Setup] +AppName=My Program +AppVersion=1.5 +CreateAppDir=no +DisableProgramGroupPage=yes +DefaultGroupName=My Program +UninstallDisplayIcon={app}\MyProg.exe +OutputDir=userdocs:Inno Setup Examples Output + +[Code] + +{--- IShellLink ---} + +const + CLSID_ShellLink = '{00021401-0000-0000-C000-000000000046}'; + +type + IShellLinkW = interface(IUnknown) + '{000214F9-0000-0000-C000-000000000046}' + procedure Dummy; + procedure Dummy2; + procedure Dummy3; + function GetDescription(pszName: String; cchMaxName: Integer): HResult; + function SetDescription(pszName: String): HResult; + function GetWorkingDirectory(pszDir: String; cchMaxPath: Integer): HResult; + function SetWorkingDirectory(pszDir: String): HResult; + function GetArguments(pszArgs: String; cchMaxPath: Integer): HResult; + function SetArguments(pszArgs: String): HResult; + function GetHotkey(var pwHotkey: Word): HResult; + function SetHotkey(wHotkey: Word): HResult; + function GetShowCmd(out piShowCmd: Integer): HResult; + function SetShowCmd(iShowCmd: Integer): HResult; + function GetIconLocation(pszIconPath: String; cchIconPath: Integer; + out piIcon: Integer): HResult; + function SetIconLocation(pszIconPath: String; iIcon: Integer): HResult; + function SetRelativePath(pszPathRel: String; dwReserved: DWORD): HResult; + function Resolve(Wnd: HWND; fFlags: DWORD): HResult; + function SetPath(pszFile: String): HResult; + end; + + IPersist = interface(IUnknown) + '{0000010C-0000-0000-C000-000000000046}' + function GetClassID(var classID: TGUID): HResult; + end; + + IPersistFile = interface(IPersist) + '{0000010B-0000-0000-C000-000000000046}' + function IsDirty: HResult; + function Load(pszFileName: String; dwMode: Longint): HResult; + function Save(pszFileName: String; fRemember: BOOL): HResult; + function SaveCompleted(pszFileName: String): HResult; + function GetCurFile(out pszFileName: String): HResult; + end; + +procedure IShellLinkButtonOnClick(Sender: TObject); +var + Obj: IUnknown; + SL: IShellLinkW; + PF: IPersistFile; +begin + { Create the main ShellLink COM Automation object } + Obj := CreateComObject(StringToGuid(CLSID_ShellLink)); + + { Set the shortcut properties } + SL := IShellLinkW(Obj); + OleCheck(SL.SetPath(ExpandConstant('{srcexe}'))); + OleCheck(SL.SetArguments('')); + OleCheck(SL.SetShowCmd(SW_SHOWNORMAL)); + + { Save the shortcut } + PF := IPersistFile(Obj); + OleCheck(PF.Save(ExpandConstant('{commondesktop}\CodeAutomation2 Test.lnk'), True)); + + MsgBox('Saved a shortcut named ''CodeAutomation2 Test'' on the common desktop.', mbInformation, mb_Ok); +end; + +{--- ITaskScheduler ---} + +const + CLSID_TaskScheduler = '{148BD52A-A2AB-11CE-B11F-00AA00530503}'; + CLSID_Task = '{148BD520-A2AB-11CE-B11F-00AA00530503}'; + IID_Task = '{148BD524-A2AB-11CE-B11F-00AA00530503}'; + TASK_TIME_TRIGGER_DAILY = 1; + +type + ITaskScheduler = interface(IUnknown) + '{148BD527-A2AB-11CE-B11F-00AA00530503}' + function SetTargetComputer(pwszComputer: String): HResult; + function GetTargetComputer(out ppwszComputer: String): HResult; + procedure Dummy; + function Activate(pwszName: String; var riid: TGUID; out ppUnk: IUnknown): HResult; + function Delete(pwszName: String): HResult; + function NewWorkItem(pwszTaskName: String; var rclsid: TGUID; var riid: TGUID; out ppUnk: IUnknown): HResult; + procedure Dummy2; + function IsOfType(pwszName: String; var riid: TGUID): HResult; + end; + + TDaily = record + DaysInterval: WORD; + end; + + TWeekly = record + WeeksInterval: WORD; + rgfDaysOfTheWeek: WORD; + end; + + TMonthyDate = record + rgfDays: DWORD; + rgfMonths: WORD; + end; + + TMonthlyDow = record + wWhichWeek: WORD; + rgfDaysOfTheWeek: WORD; + rgfMonths: WORD; + end; + + { ROPS doesn't support unions, replace this with the type you need and adjust padding (end size has to be 48). } + TTriggerTypeUnion = record + Daily: TDaily; + Pad1: WORD; + Pad2: WORD; + Pad3: WORD; + end; + + TTaskTrigger = record + cbTriggerSize: WORD; + Reserved1: WORD; + wBeginYear: WORD; + wBeginMonth: WORD; + wBeginDay: WORD; + wEndYear: WORD; + wEndMonth: WORD; + wEndDay: WORD; + wStartHour: WORD; + wStartMinute: WORD; + MinutesDuration: DWORD; + MinutesInterval: DWORD; + rgFlags: DWORD; + TriggerType: DWORD; + Type_: TTriggerTypeUnion; + Reserved2: WORD; + wRandomMinutesInterval: WORD; + end; + + ITaskTrigger = interface(IUnknown) + '{148BD52B-A2AB-11CE-B11F-00AA00530503}' + function SetTrigger(var pTrigger: TTaskTrigger): HResult; + function GetTrigger(var pTrigger: TTaskTrigger): HResult; + function GetTriggerString(var ppwszTrigger: String): HResult; + end; + + IScheduledWorkItem = interface(IUnknown) + '{A6B952F0-A4B1-11D0-997D-00AA006887EC}' + function CreateTrigger(out piNewTrigger: Word; out ppTrigger: ITaskTrigger): HResult; + function DeleteTrigger(iTrigger: Word): HResult; + function GetTriggerCount(out pwCount: Word): HResult; + function GetTrigger(iTrigger: Word; var ppTrigger: ITaskTrigger): HResult; + function GetTriggerString(iTrigger: Word; out ppwszTrigger: String): HResult; + procedure Dummy; + procedure Dummy2; + function SetIdleWait(wIdleMinutes: Word; wDeadlineMinutes: Word): HResult; + function GetIdleWait(out pwIdleMinutes: Word; out pwDeadlineMinutes: Word): HResult; + function Run: HResult; + function Terminate: HResult; + function EditWorkItem(hParent: HWND; dwReserved: DWORD): HResult; + procedure Dummy3; + function GetStatus(out phrStatus: HResult): HResult; + function GetExitCode(out pdwExitCode: DWORD): HResult; + function SetComment(pwszComment: String): HResult; + function GetComment(out ppwszComment: String): HResult; + function SetCreator(pwszCreator: String): HResult; + function GetCreator(out ppwszCreator: String): HResult; + function SetWorkItemData(cbData: Word; var rgbData: Byte): HResult; + function GetWorkItemData(out pcbData: Word; out prgbData: Byte): HResult; + function SetErrorRetryCount(wRetryCount: Word): HResult; + function GetErrorRetryCount(out pwRetryCount: Word): HResult; + function SetErrorRetryInterval(wRetryInterval: Word): HResult; + function GetErrorRetryInterval(out pwRetryInterval: Word): HResult; + function SetFlags(dwFlags: DWORD): HResult; + function GetFlags(out pdwFlags: DWORD): HResult; + function SetAccountInformation(pwszAccountName: String; pwszPassword: String): HResult; + function GetAccountInformation(out ppwszAccountName: String): HResult; + end; + + ITask = interface(IScheduledWorkItem) + '{148BD524-A2AB-11CE-B11F-00AA00530503}' + function SetApplicationName(pwszApplicationName: String): HResult; + function GetApplicationName(out ppwszApplicationName: String): HResult; + function SetParameters(pwszParameters: String): HResult; + function GetParameters(out ppwszParameters: String): HResult; + function SetWorkingDirectory(pwszWorkingDirectory: String): HResult; + function GetWorkingDirectory(out ppwszWorkingDirectory: String): HResult; + function SetPriority(dwPriority: DWORD): HResult; + function GetPriority(out pdwPriority: DWORD): HResult; + function SetTaskFlags(dwFlags: DWORD): HResult; + function GetTaskFlags(out pdwFlags: DWORD): HResult; + function SetMaxRunTime(dwMaxRunTimeMS: DWORD): HResult; + function GetMaxRunTime(out pdwMaxRunTimeMS: DWORD): HResult; + end; + + +procedure ITaskSchedulerButtonOnClick(Sender: TObject); +var + Obj, Obj2: IUnknown; + TaskScheduler: ITaskScheduler; + G1, G2: TGUID; + Task: ITask; + iNewTrigger: WORD; + TaskTrigger: ITaskTrigger; + TaskTrigger2: TTaskTrigger; + PF: IPersistFile; +begin + { Create the main TaskScheduler COM Automation object } + Obj := CreateComObject(StringToGuid(CLSID_TaskScheduler)); + + { Create the Task COM automation object } + TaskScheduler := ITaskScheduler(Obj); + G1 := StringToGuid(CLSID_Task); + G2 := StringToGuid(IID_Task); + //This will throw an exception if the task already exists + OleCheck(TaskScheduler.NewWorkItem('CodeAutomation2 Test', G1, G2, Obj2)); + + { Set the task properties } + Task := ITask(Obj2); + OleCheck(Task.SetComment('CodeAutomation2 Test Comment')); + OleCheck(Task.SetApplicationName(ExpandConstant('{srcexe}'))); + + { Set the task account information } + //Uncomment the following and provide actual user info to get a runnable task + //OleCheck(Task.SetAccountInformation('username', 'password')); + + { Create the TaskTrigger COM automation object } + OleCheck(Task.CreateTrigger(iNewTrigger, TaskTrigger)); + + { Set the task trigger properties } + with TaskTrigger2 do begin + cbTriggerSize := SizeOf(TaskTrigger2); + wBeginYear := 2009; + wBeginMonth := 10; + wBeginDay := 1; + wStartHour := 12; + TriggerType := TASK_TIME_TRIGGER_DAILY; + Type_.Daily.DaysInterval := 1; + end; + OleCheck(TaskTrigger.SetTrigger(TaskTrigger2)); + + { Save the task } + PF := IPersistFile(Obj2); + OleCheck(PF.Save('', True)); + + MsgBox('Created a daily task named named ''CodeAutomation2 Test''.' + #13#13 + 'Note: Account information not set so the task won''t actually run, uncomment the SetAccountInfo call and provide actual user info to get a runnable task.', mbInformation, mb_Ok); +end; + +{---} + +procedure CreateButton(ALeft, ATop: Integer; ACaption: String; ANotifyEvent: TNotifyEvent); +begin + with TButton.Create(WizardForm) do begin + Left := ALeft; + Top := ATop; + Width := (WizardForm.CancelButton.Width*3)/2; + Height := WizardForm.CancelButton.Height; + Caption := ACaption; + OnClick := ANotifyEvent; + Parent := WizardForm.WelcomePage; + end; +end; + +procedure InitializeWizard(); +var + Left, LeftInc, Top, TopInc: Integer; +begin + Left := WizardForm.WelcomeLabel2.Left; + LeftInc := (WizardForm.CancelButton.Width*3)/2 + ScaleX(8); + TopInc := WizardForm.CancelButton.Height + ScaleY(8); + Top := WizardForm.WelcomeLabel2.Top + WizardForm.WelcomeLabel2.Height - 4*TopInc; + + CreateButton(Left, Top, '&IShellLink...', @IShellLinkButtonOnClick); + Top := Top + TopInc; + CreateButton(Left, Top, '&ITaskScheduler...', @ITaskSchedulerButtonOnClick); +end; + + + + + diff --git a/Greenshot/tools/innosetup/Examples/CodeClasses.iss b/Greenshot/tools/innosetup/Examples/CodeClasses.iss new file mode 100644 index 000000000..28a3b8b87 --- /dev/null +++ b/Greenshot/tools/innosetup/Examples/CodeClasses.iss @@ -0,0 +1,331 @@ +; -- CodeClasses.iss -- +; +; This script shows how to use the WizardForm object and the various VCL classes. + +[Setup] +AppName=My Program +AppVersion=1.5 +CreateAppDir=no +DisableProgramGroupPage=yes +DefaultGroupName=My Program +UninstallDisplayIcon={app}\MyProg.exe +WindowVisible=yes +OutputDir=userdocs:Inno Setup Examples Output + +[Files] +Source: compiler:WizModernSmallImage.bmp; Flags: dontcopy + +[Code] +procedure ButtonOnClick(Sender: TObject); +begin + MsgBox('You clicked the button!', mbInformation, mb_Ok); +end; + +procedure FormButtonOnClick(Sender: TObject); +var + Form: TSetupForm; + OKButton, CancelButton: TNewButton; +begin + Form := CreateCustomForm(); + try + Form.ClientWidth := ScaleX(256); + Form.ClientHeight := ScaleY(256); + Form.Caption := 'TSetupForm'; + Form.CenterInsideControl(WizardForm, False); + + OKButton := TNewButton.Create(Form); + OKButton.Parent := Form; + OKButton.Width := ScaleX(75); + OKButton.Height := ScaleY(23); + OKButton.Left := Form.ClientWidth - ScaleX(75 + 6 + 75 + 10); + OKButton.Top := Form.ClientHeight - ScaleY(23 + 10); + OKButton.Caption := 'OK'; + OKButton.ModalResult := mrOk; + + CancelButton := TNewButton.Create(Form); + CancelButton.Parent := Form; + CancelButton.Width := ScaleX(75); + CancelButton.Height := ScaleY(23); + CancelButton.Left := Form.ClientWidth - ScaleX(75 + 10); + CancelButton.Top := Form.ClientHeight - ScaleY(23 + 10); + CancelButton.Caption := 'Cancel'; + CancelButton.ModalResult := mrCancel; + CancelButton.Cancel := True; + + Form.ActiveControl := OKButton; + + if Form.ShowModal() = mrOk then + MsgBox('You clicked OK.', mbInformation, MB_OK); + finally + Form.Free(); + end; +end; + +procedure CreateTheWizardPages; +var + Page: TWizardPage; + Button, FormButton: TNewButton; + Panel: TPanel; + CheckBox: TNewCheckBox; + Edit: TNewEdit; + PasswordEdit: TPasswordEdit; + Memo: TNewMemo; + ComboBox: TNewComboBox; + ListBox: TNewListBox; + StaticText, ProgressBarLabel: TNewStaticText; + ProgressBar: TNewProgressBar; + CheckListBox, CheckListBox2: TNewCheckListBox; + FolderTreeView: TFolderTreeView; + BitmapImage, BitmapImage2, BitmapImage3: TBitmapImage; + BitmapFileName: String; + RichEditViewer: TRichEditViewer; +begin + { TButton and others } + + Page := CreateCustomPage(wpWelcome, 'Custom wizard page controls', 'TButton and others'); + + Button := TNewButton.Create(Page); + Button.Width := ScaleX(75); + Button.Height := ScaleY(23); + Button.Caption := 'TNewButton'; + Button.OnClick := @ButtonOnClick; + Button.Parent := Page.Surface; + + Panel := TPanel.Create(Page); + Panel.Width := Page.SurfaceWidth div 2 - ScaleX(8); + Panel.Left := Page.SurfaceWidth - Panel.Width; + Panel.Height := Button.Height * 2; + Panel.Caption := 'TPanel'; + Panel.Color := clWindow; + Panel.ParentBackground := False; + Panel.Parent := Page.Surface; + + CheckBox := TNewCheckBox.Create(Page); + CheckBox.Top := Button.Top + Button.Height + ScaleY(8); + CheckBox.Width := Page.SurfaceWidth div 2; + CheckBox.Height := ScaleY(17); + CheckBox.Caption := 'TNewCheckBox'; + CheckBox.Checked := True; + CheckBox.Parent := Page.Surface; + + Edit := TNewEdit.Create(Page); + Edit.Top := CheckBox.Top + CheckBox.Height + ScaleY(8); + Edit.Width := Page.SurfaceWidth div 2 - ScaleX(8); + Edit.Text := 'TNewEdit'; + Edit.Parent := Page.Surface; + + PasswordEdit := TPasswordEdit.Create(Page); + PasswordEdit.Left := Page.SurfaceWidth - Edit.Width; + PasswordEdit.Top := CheckBox.Top + CheckBox.Height + ScaleY(8); + PasswordEdit.Width := Edit.Width; + PasswordEdit.Text := 'TPasswordEdit'; + PasswordEdit.Parent := Page.Surface; + + Memo := TNewMemo.Create(Page); + Memo.Top := Edit.Top + Edit.Height + ScaleY(8); + Memo.Width := Page.SurfaceWidth; + Memo.Height := ScaleY(89); + Memo.ScrollBars := ssVertical; + Memo.Text := 'TNewMemo'; + Memo.Parent := Page.Surface; + + FormButton := TNewButton.Create(Page); + FormButton.Top := Memo.Top + Memo.Height + ScaleY(8); + FormButton.Width := ScaleX(75); + FormButton.Height := ScaleY(23); + FormButton.Caption := 'TSetupForm'; + FormButton.OnClick := @FormButtonOnClick; + FormButton.Parent := Page.Surface; + + { TComboBox and others } + + Page := CreateCustomPage(Page.ID, 'Custom wizard page controls', 'TComboBox and others'); + + ComboBox := TNewComboBox.Create(Page); + ComboBox.Width := Page.SurfaceWidth; + ComboBox.Parent := Page.Surface; + ComboBox.Style := csDropDownList; + ComboBox.Items.Add('TComboBox'); + ComboBox.ItemIndex := 0; + + ListBox := TNewListBox.Create(Page); + ListBox.Top := ComboBox.Top + ComboBox.Height + ScaleY(8); + ListBox.Width := Page.SurfaceWidth; + ListBox.Height := ScaleY(97); + ListBox.Parent := Page.Surface; + ListBox.Items.Add('TListBox'); + ListBox.ItemIndex := 0; + + StaticText := TNewStaticText.Create(Page); + StaticText.Top := ListBox.Top + ListBox.Height + ScaleY(8); + StaticText.Caption := 'TNewStaticText'; + StaticText.AutoSize := True; + StaticText.Parent := Page.Surface; + + ProgressBarLabel := TNewStaticText.Create(Page); + ProgressBarLabel.Top := StaticText.Top + StaticText.Height + ScaleY(8); + ProgressBarLabel.Caption := 'TNewProgressBar'; + ProgressBarLabel.AutoSize := True; + ProgressBarLabel.Parent := Page.Surface; + + ProgressBar := TNewProgressBar.Create(Page); + ProgressBar.Left := ProgressBarLabel.Width + ScaleX(8); + ProgressBar.Top := ProgressBarLabel.Top; + ProgressBar.Width := Page.SurfaceWidth - ProgressBar.Left; + ProgressBar.Height := ProgressBarLabel.Height + ScaleY(8); + ProgressBar.Parent := Page.Surface; + ProgressBar.Position := 25; + + { TNewCheckListBox } + + Page := CreateCustomPage(Page.ID, 'Custom wizard page controls', 'TNewCheckListBox'); + + CheckListBox := TNewCheckListBox.Create(Page); + CheckListBox.Width := Page.SurfaceWidth; + CheckListBox.Height := ScaleY(97); + CheckListBox.Flat := True; + CheckListBox.Parent := Page.Surface; + CheckListBox.AddCheckBox('TNewCheckListBox', '', 0, True, True, False, True, nil); + CheckListBox.AddRadioButton('TNewCheckListBox', '', 1, True, True, nil); + CheckListBox.AddRadioButton('TNewCheckListBox', '', 1, False, True, nil); + CheckListBox.AddCheckBox('TNewCheckListBox', '', 0, True, True, False, True, nil); + + CheckListBox2 := TNewCheckListBox.Create(Page); + CheckListBox2.Top := CheckListBox.Top + CheckListBox.Height + ScaleY(8); + CheckListBox2.Width := Page.SurfaceWidth; + CheckListBox2.Height := ScaleY(97); + CheckListBox2.BorderStyle := bsNone; + CheckListBox2.ParentColor := True; + CheckListBox2.MinItemHeight := WizardForm.TasksList.MinItemHeight; + CheckListBox2.ShowLines := False; + CheckListBox2.WantTabs := True; + CheckListBox2.Parent := Page.Surface; + CheckListBox2.AddGroup('TNewCheckListBox', '', 0, nil); + CheckListBox2.AddRadioButton('TNewCheckListBox', '', 0, True, True, nil); + CheckListBox2.AddRadioButton('TNewCheckListBox', '', 0, False, True, nil); + + { TFolderTreeView } + + Page := CreateCustomPage(Page.ID, 'Custom wizard page controls', 'TFolderTreeView'); + + FolderTreeView := TFolderTreeView.Create(Page); + FolderTreeView.Width := Page.SurfaceWidth; + FolderTreeView.Height := Page.SurfaceHeight; + FolderTreeView.Parent := Page.Surface; + FolderTreeView.Directory := ExpandConstant('{src}'); + + { TBitmapImage } + + Page := CreateCustomPage(Page.ID, 'Custom wizard page controls', 'TBitmapImage'); + + BitmapFileName := ExpandConstant('{tmp}\WizModernSmallImage.bmp'); + ExtractTemporaryFile(ExtractFileName(BitmapFileName)); + + BitmapImage := TBitmapImage.Create(Page); + BitmapImage.AutoSize := True; + BitmapImage.Bitmap.LoadFromFile(BitmapFileName); + BitmapImage.Parent := Page.Surface; + + BitmapImage2 := TBitmapImage.Create(Page); + BitmapImage2.BackColor := $400000; + BitmapImage2.Bitmap := BitmapImage.Bitmap; + BitmapImage2.Center := True; + BitmapImage2.Left := BitmapImage.Width + 10; + BitmapImage2.Height := 2*BitmapImage.Height; + BitmapImage2.Width := 2*BitmapImage.Width; + BitmapImage2.Parent := Page.Surface; + + BitmapImage3 := TBitmapImage.Create(Page); + BitmapImage3.Bitmap := BitmapImage.Bitmap; + BitmapImage3.Stretch := True; + BitmapImage3.Left := 3*BitmapImage.Width + 20; + BitmapImage3.Height := 4*BitmapImage.Height; + BitmapImage3.Width := 4*BitmapImage.Width; + BitmapImage3.Parent := Page.Surface; + + { TRichViewer } + + Page := CreateCustomPage(Page.ID, 'Custom wizard page controls', 'TRichViewer'); + + RichEditViewer := TRichEditViewer.Create(Page); + RichEditViewer.Width := Page.SurfaceWidth; + RichEditViewer.Height := Page.SurfaceHeight; + RichEditViewer.Parent := Page.Surface; + RichEditViewer.ScrollBars := ssVertical; + RichEditViewer.UseRichEdit := True; + RichEditViewer.RTFText := '{\rtf1\ansi\ansicpg1252\deff0\deflang1043{\fonttbl{\f0\fswiss\fcharset0 Arial;}}{\colortbl ;\red255\green0\blue0;\red0\green128\blue0;\red0\green0\blue128;}\viewkind4\uc1\pard\f0\fs20 T\cf1 Rich\cf2 Edit\cf3 Viewer\cf0\par}'; + RichEditViewer.ReadOnly := True; +end; + +procedure AboutButtonOnClick(Sender: TObject); +begin + MsgBox('This demo shows some features of the various form objects and control classes.', mbInformation, mb_Ok); +end; + +procedure URLLabelOnClick(Sender: TObject); +var + ErrorCode: Integer; +begin + ShellExec('open', 'http://www.innosetup.com', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); +end; + +procedure CreateAboutButtonAndURLLabel(ParentForm: TSetupForm; CancelButton: TNewButton); +var + AboutButton: TNewButton; + URLLabel: TNewStaticText; +begin + AboutButton := TNewButton.Create(ParentForm); + AboutButton.Left := ParentForm.ClientWidth - CancelButton.Left - CancelButton.Width; + AboutButton.Top := CancelButton.Top; + AboutButton.Width := CancelButton.Width; + AboutButton.Height := CancelButton.Height; + AboutButton.Caption := '&About...'; + AboutButton.OnClick := @AboutButtonOnClick; + AboutButton.Parent := ParentForm; + + URLLabel := TNewStaticText.Create(ParentForm); + URLLabel.Caption := 'www.innosetup.com'; + URLLabel.Cursor := crHand; + URLLabel.OnClick := @URLLabelOnClick; + URLLabel.Parent := ParentForm; + { Alter Font *after* setting Parent so the correct defaults are inherited first } + URLLabel.Font.Style := URLLabel.Font.Style + [fsUnderline]; + URLLabel.Font.Color := clBlue; + URLLabel.Top := AboutButton.Top + AboutButton.Height - URLLabel.Height - 2; + URLLabel.Left := AboutButton.Left + AboutButton.Width + ScaleX(20); +end; + +procedure InitializeWizard(); +var + BackgroundBitmapImage: TBitmapImage; + BackgroundBitmapText: TNewStaticText; +begin + { Custom wizard pages } + + CreateTheWizardPages; + + { Custom controls } + + CreateAboutButtonAndURLLabel(WizardForm, WizardForm.CancelButton); + + BackgroundBitmapImage := TBitmapImage.Create(MainForm); + BackgroundBitmapImage.Left := 50; + BackgroundBitmapImage.Top := 90; + BackgroundBitmapImage.AutoSize := True; + BackgroundBitmapImage.Bitmap := WizardForm.WizardBitmapImage.Bitmap; + BackgroundBitmapImage.Parent := MainForm; + + BackgroundBitmapText := TNewStaticText.Create(MainForm); + BackgroundBitmapText.Left := BackgroundBitmapImage.Left; + BackgroundBitmapText.Top := BackgroundBitmapImage.Top + BackgroundBitmapImage.Height + ScaleY(8); + BackgroundBitmapText.Caption := 'TBitmapImage'; + BackgroundBitmapText.Parent := MainForm; +end; + +procedure InitializeUninstallProgressForm(); +begin + { Custom controls } + + CreateAboutButtonAndURLLabel(UninstallProgressForm, UninstallProgressForm.CancelButton); +end; + diff --git a/Greenshot/tools/innosetup/Examples/CodeDlg.iss b/Greenshot/tools/innosetup/Examples/CodeDlg.iss new file mode 100644 index 000000000..b9674aba9 --- /dev/null +++ b/Greenshot/tools/innosetup/Examples/CodeDlg.iss @@ -0,0 +1,204 @@ +; -- CodeDlg.iss -- +; +; This script shows how to insert custom wizard pages into Setup and how to handle +; these pages. Furthermore it shows how to 'communicate' between the [Code] section +; and the regular Inno Setup sections using {code:...} constants. Finally it shows +; how to customize the settings text on the 'Ready To Install' page. + +[Setup] +AppName=My Program +AppVersion=1.5 +DefaultDirName={pf}\My Program +DisableProgramGroupPage=yes +UninstallDisplayIcon={app}\MyProg.exe +OutputDir=userdocs:Inno Setup Examples Output + +[Files] +Source: "MyProg.exe"; DestDir: "{app}" +Source: "MyProg.chm"; DestDir: "{app}" +Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme + +[Registry] +Root: HKCU; Subkey: "Software\My Company"; Flags: uninsdeletekeyifempty +Root: HKCU; Subkey: "Software\My Company\My Program"; Flags: uninsdeletekey +Root: HKCU; Subkey: "Software\My Company\My Program\Settings"; ValueType: string; ValueName: "Name"; ValueData: "{code:GetUser|Name}" +Root: HKCU; Subkey: "Software\My Company\My Program\Settings"; ValueType: string; ValueName: "Company"; ValueData: "{code:GetUser|Company}" +Root: HKCU; Subkey: "Software\My Company\My Program\Settings"; ValueType: string; ValueName: "DataDir"; ValueData: "{code:GetDataDir}" +; etc. + +[Dirs] +Name: {code:GetDataDir}; Flags: uninsneveruninstall + +[Code] +var + UserPage: TInputQueryWizardPage; + UsagePage: TInputOptionWizardPage; + LightMsgPage: TOutputMsgWizardPage; + KeyPage: TInputQueryWizardPage; + ProgressPage: TOutputProgressWizardPage; + DataDirPage: TInputDirWizardPage; + +procedure InitializeWizard; +begin + { Create the pages } + + UserPage := CreateInputQueryPage(wpWelcome, + 'Personal Information', 'Who are you?', + 'Please specify your name and the company for whom you work, then click Next.'); + UserPage.Add('Name:', False); + UserPage.Add('Company:', False); + + UsagePage := CreateInputOptionPage(UserPage.ID, + 'Personal Information', 'How will you use My Program?', + 'Please specify how you would like to use My Program, then click Next.', + True, False); + UsagePage.Add('Light mode (no ads, limited functionality)'); + UsagePage.Add('Sponsored mode (with ads, full functionality)'); + UsagePage.Add('Paid mode (no ads, full functionality)'); + + LightMsgPage := CreateOutputMsgPage(UsagePage.ID, + 'Personal Information', 'How will you use My Program?', + 'Note: to enjoy all features My Program can offer and to support its development, ' + + 'you can switch to sponsored or paid mode at any time by selecting ''Usage Mode'' ' + + 'in the ''Help'' menu of My Program after the installation has completed.'#13#13 + + 'Click Back if you want to change your usage mode setting now, or click Next to ' + + 'continue with the installation.'); + + KeyPage := CreateInputQueryPage(UsagePage.ID, + 'Personal Information', 'What''s your registration key?', + 'Please specify your registration key and click Next to continue. If you don''t ' + + 'have a valid registration key, click Back to choose a different usage mode.'); + KeyPage.Add('Registration key:', False); + + ProgressPage := CreateOutputProgressPage('Personal Information', + 'What''s your registration key?'); + + DataDirPage := CreateInputDirPage(wpSelectDir, + 'Select Personal Data Directory', 'Where should personal data files be installed?', + 'Select the folder in which Setup should install personal data files, then click Next.', + False, ''); + DataDirPage.Add(''); + + { Set default values, using settings that were stored last time if possible } + + UserPage.Values[0] := GetPreviousData('Name', ExpandConstant('{sysuserinfoname}')); + UserPage.Values[1] := GetPreviousData('Company', ExpandConstant('{sysuserinfoorg}')); + + case GetPreviousData('UsageMode', '') of + 'light': UsagePage.SelectedValueIndex := 0; + 'sponsored': UsagePage.SelectedValueIndex := 1; + 'paid': UsagePage.SelectedValueIndex := 2; + else + UsagePage.SelectedValueIndex := 1; + end; + + DataDirPage.Values[0] := GetPreviousData('DataDir', ''); +end; + +procedure RegisterPreviousData(PreviousDataKey: Integer); +var + UsageMode: String; +begin + { Store the settings so we can restore them next time } + SetPreviousData(PreviousDataKey, 'Name', UserPage.Values[0]); + SetPreviousData(PreviousDataKey, 'Company', UserPage.Values[1]); + case UsagePage.SelectedValueIndex of + 0: UsageMode := 'light'; + 1: UsageMode := 'sponsored'; + 2: UsageMode := 'paid'; + end; + SetPreviousData(PreviousDataKey, 'UsageMode', UsageMode); + SetPreviousData(PreviousDataKey, 'DataDir', DataDirPage.Values[0]); +end; + +function ShouldSkipPage(PageID: Integer): Boolean; +begin + { Skip pages that shouldn't be shown } + if (PageID = LightMsgPage.ID) and (UsagePage.SelectedValueIndex <> 0) then + Result := True + else if (PageID = KeyPage.ID) and (UsagePage.SelectedValueIndex <> 2) then + Result := True + else + Result := False; +end; + +function NextButtonClick(CurPageID: Integer): Boolean; +var + I: Integer; +begin + { Validate certain pages before allowing the user to proceed } + if CurPageID = UserPage.ID then begin + if UserPage.Values[0] = '' then begin + MsgBox('You must enter your name.', mbError, MB_OK); + Result := False; + end else begin + if DataDirPage.Values[0] = '' then + DataDirPage.Values[0] := 'C:\' + UserPage.Values[0]; + Result := True; + end; + end else if CurPageID = KeyPage.ID then begin + { Just to show how 'OutputProgress' pages work. + Always use a try..finally between the Show and Hide calls as shown below. } + ProgressPage.SetText('Authorizing registration key...', ''); + ProgressPage.SetProgress(0, 0); + ProgressPage.Show; + try + for I := 0 to 10 do begin + ProgressPage.SetProgress(I, 10); + Sleep(100); + end; + finally + ProgressPage.Hide; + end; + if KeyPage.Values[0] = 'inno' then + Result := True + else begin + MsgBox('You must enter a valid registration key. (Hint: The key is "inno".)', mbError, MB_OK); + Result := False; + end; + end else + Result := True; +end; + +function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, + MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String; +var + S: String; +begin + { Fill the 'Ready Memo' with the normal settings and the custom settings } + S := ''; + S := S + 'Personal Information:' + NewLine; + S := S + Space + UserPage.Values[0] + NewLine; + if UserPage.Values[1] <> '' then + S := S + Space + UserPage.Values[1] + NewLine; + S := S + NewLine; + + S := S + 'Usage Mode:' + NewLine + Space; + case UsagePage.SelectedValueIndex of + 0: S := S + 'Light mode'; + 1: S := S + 'Sponsored mode'; + 2: S := S + 'Paid mode'; + end; + S := S + NewLine + NewLine; + + S := S + MemoDirInfo + NewLine; + S := S + Space + DataDirPage.Values[0] + ' (personal data files)' + NewLine; + + Result := S; +end; + +function GetUser(Param: String): String; +begin + { Return a user value } + { Could also be split into separate GetUserName and GetUserCompany functions } + if Param = 'Name' then + Result := UserPage.Values[0] + else if Param = 'Company' then + Result := UserPage.Values[1]; +end; + +function GetDataDir(Param: String): String; +begin + { Return the selected DataDir } + Result := DataDirPage.Values[0]; +end; diff --git a/Greenshot/tools/innosetup/Examples/CodeDll.iss b/Greenshot/tools/innosetup/Examples/CodeDll.iss new file mode 100644 index 000000000..979287b12 --- /dev/null +++ b/Greenshot/tools/innosetup/Examples/CodeDll.iss @@ -0,0 +1,72 @@ +; -- CodeDll.iss -- +; +; This script shows how to call DLL functions at runtime from a [Code] section. + +[Setup] +AppName=My Program +AppVersion=1.5 +DefaultDirName={pf}\My Program +DisableProgramGroupPage=yes +UninstallDisplayIcon={app}\MyProg.exe +OutputDir=userdocs:Inno Setup Examples Output + +[Files] +Source: "MyProg.exe"; DestDir: "{app}" +Source: "MyProg.chm"; DestDir: "{app}" +Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme +; Install our DLL to {app} so we can access it at uninstall time +; Use "Flags: dontcopy" if you don't need uninstall time access +Source: "MyDll.dll"; DestDir: "{app}" + +[Code] +const + MB_ICONINFORMATION = $40; + +//importing a Windows API function +function MessageBox(hWnd: Integer; lpText, lpCaption: AnsiString; uType: Cardinal): Integer; +external 'MessageBoxA@user32.dll stdcall'; + +//importing a custom DLL function, first for Setup, then for uninstall +procedure MyDllFuncSetup(hWnd: Integer; lpText, lpCaption: AnsiString; uType: Cardinal); +external 'MyDllFunc@files:MyDll.dll stdcall setuponly'; + +procedure MyDllFuncUninstall(hWnd: Integer; lpText, lpCaption: AnsiString; uType: Cardinal); +external 'MyDllFunc@{app}\MyDll.dll stdcall uninstallonly'; + +//importing a function for a DLL which might not exist at runtime +procedure DelayLoadedFunc(hWnd: Integer; lpText, lpCaption: AnsiString; uType: Cardinal); +external 'DllFunc@DllWhichMightNotExist.dll stdcall delayload'; + +function NextButtonClick(CurPage: Integer): Boolean; +var + hWnd: Integer; +begin + if CurPage = wpWelcome then begin + hWnd := StrToInt(ExpandConstant('{wizardhwnd}')); + + MessageBox(hWnd, 'Hello from Windows API function', 'MessageBoxA', MB_OK or MB_ICONINFORMATION); + + MyDllFuncSetup(hWnd, 'Hello from custom DLL function', 'MyDllFunc', MB_OK or MB_ICONINFORMATION); + + try + //if this DLL does not exist (it shouldn't), an exception will be raised + DelayLoadedFunc(hWnd, 'Hello from delay loaded function', 'DllFunc', MB_OK or MB_ICONINFORMATION); + except + //handle missing dll here + end; + end; + Result := True; +end; + +procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); +begin + // Call our function just before the actual uninstall process begins + if CurUninstallStep = usUninstall then + begin + MyDllFuncUninstall(0, 'Hello from custom DLL function', 'MyDllFunc', MB_OK or MB_ICONINFORMATION); + + // Now that we're finished with it, unload MyDll.dll from memory. + // We have to do this so that the uninstaller will be able to remove the DLL and the {app} directory. + UnloadDLL(ExpandConstant('{app}\MyDll.dll')); + end; +end; diff --git a/Greenshot/tools/innosetup/Examples/CodeExample1.iss b/Greenshot/tools/innosetup/Examples/CodeExample1.iss new file mode 100644 index 000000000..edbeb1e02 --- /dev/null +++ b/Greenshot/tools/innosetup/Examples/CodeExample1.iss @@ -0,0 +1,149 @@ +; -- CodeExample1.iss -- +; +; This script shows various things you can achieve using a [Code] section + +[Setup] +AppName=My Program +AppVersion=1.5 +DefaultDirName={code:MyConst}\My Program +DefaultGroupName=My Program +UninstallDisplayIcon={app}\MyProg.exe +InfoBeforeFile=Readme.txt +OutputDir=userdocs:Inno Setup Examples Output + +[Files] +Source: "MyProg.exe"; DestDir: "{app}"; Check: MyProgCheck; BeforeInstall: BeforeMyProgInstall('MyProg.exe'); AfterInstall: AfterMyProgInstall('MyProg.exe') +Source: "MyProg.chm"; DestDir: "{app}"; Check: MyProgCheck; BeforeInstall: BeforeMyProgInstall('MyProg.chm'); AfterInstall: AfterMyProgInstall('MyProg.chm') +Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme + +[Icons] +Name: "{group}\My Program"; Filename: "{app}\MyProg.exe" + +[Code] +var + MyProgChecked: Boolean; + MyProgCheckResult: Boolean; + FinishedInstall: Boolean; + +function InitializeSetup(): Boolean; +begin + Log('InitializeSetup called'); + Result := MsgBox('InitializeSetup:' #13#13 'Setup is initializing. Do you really want to start setup?', mbConfirmation, MB_YESNO) = idYes; + if Result = False then + MsgBox('InitializeSetup:' #13#13 'Ok, bye bye.', mbInformation, MB_OK); +end; + +procedure DeinitializeSetup(); +var + FileName: String; + ResultCode: Integer; +begin + Log('DeinitializeSetup called'); + if FinishedInstall then begin + if MsgBox('DeinitializeSetup:' #13#13 'The [Code] scripting demo has finished. Do you want to uninstall My Program now?', mbConfirmation, MB_YESNO) = idYes then begin + FileName := ExpandConstant('{uninstallexe}'); + if not Exec(FileName, '', '', SW_SHOWNORMAL, ewNoWait, ResultCode) then + MsgBox('DeinitializeSetup:' #13#13 'Execution of ''' + FileName + ''' failed. ' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK); + end else + MsgBox('DeinitializeSetup:' #13#13 'Ok, bye bye.', mbInformation, MB_OK); + end; +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + Log('CurStepChanged(' + IntToStr(Ord(CurStep)) + ') called'); + if CurStep = ssPostInstall then + FinishedInstall := True; +end; + +function NextButtonClick(CurPageID: Integer): Boolean; +var + ResultCode: Integer; +begin + Log('NextButtonClick(' + IntToStr(CurPageID) + ') called'); + case CurPageID of + wpSelectDir: + MsgBox('NextButtonClick:' #13#13 'You selected: ''' + WizardDirValue + '''.', mbInformation, MB_OK); + wpSelectProgramGroup: + MsgBox('NextButtonClick:' #13#13 'You selected: ''' + WizardGroupValue + '''.', mbInformation, MB_OK); + wpReady: + begin + if MsgBox('NextButtonClick:' #13#13 'Using the script, files can be extracted before the installation starts. For example we could extract ''MyProg.exe'' now and run it.' #13#13 'Do you want to do this?', mbConfirmation, MB_YESNO) = idYes then begin + ExtractTemporaryFile('myprog.exe'); + if not Exec(ExpandConstant('{tmp}\myprog.exe'), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then + MsgBox('NextButtonClick:' #13#13 'The file could not be executed. ' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK); + end; + BringToFrontAndRestore(); + MsgBox('NextButtonClick:' #13#13 'The normal installation will now start.', mbInformation, MB_OK); + end; + end; + + Result := True; +end; + +function BackButtonClick(CurPageID: Integer): Boolean; +begin + Log('BackButtonClick(' + IntToStr(CurPageID) + ') called'); + Result := True; +end; + +function ShouldSkipPage(PageID: Integer): Boolean; +begin + Log('ShouldSkipPage(' + IntToStr(PageID) + ') called'); + { Skip wpInfoBefore page; show all others } + case PageID of + wpInfoBefore: + Result := True; + else + Result := False; + end; +end; + +procedure CurPageChanged(CurPageID: Integer); +begin + Log('CurPageChanged(' + IntToStr(CurPageID) + ') called'); + case CurPageID of + wpWelcome: + MsgBox('CurPageChanged:' #13#13 'Welcome to the [Code] scripting demo. This demo will show you some possibilities of the scripting support.' #13#13 'The scripting engine used is RemObjects Pascal Script by Carlo Kok. See http://www.remobjects.com/ps for more information.', mbInformation, MB_OK); + wpFinished: + MsgBox('CurPageChanged:' #13#13 'Welcome to final page of this demo. Click Finish to exit.', mbInformation, MB_OK); + end; +end; + +function PrepareToInstall(var NeedsRestart: Boolean): String; +begin + Log('PrepareToInstall() called'); + if MsgBox('PrepareToInstall:' #13#13 'Setup is preparing to install. Using the script you can install any prerequisites, abort Setup on errors, and request restarts. Do you want to return an error now?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2) = idYes then + Result := '