3 // Copies a NULL
-terminated
array of characters
to a
string.
4 function ArrayToString(Chars
:array of Char):String;
8 Len
:=GetArrayLength(Chars
);
12 while (i
<Len
) and (Chars
[i
]<>#
0) do begin
13 Result
[i
+1]:=Chars
[i
];
20 // Copies a
string to a NULL
-terminated
array of characters
.
21 function StringToArray(Str
:String):array of Char;
26 SetArrayLength(Result
,Len
+1);
37 // Deletes the currently processed
file as part
of Check
, BeforeInstall
or AfterInstall
38 // from the user
's virtual store to ensure the installed file is used.
39 procedure DeleteFromVirtualStore;
41 VirtualStore,FileName:String;
44 VirtualStore:=AddBackslash(ExpandConstant('{localappdata}'))+'VirtualStore
';
45 FileName:=ExpandConstant(CurrentFileName);
46 DriveChars:=Length(ExtractFileDrive(FileName));
47 if DriveChars>0 then begin
48 Delete(FileName,1,DriveChars);
49 FileName:=VirtualStore+FileName;
50 if FileExists(FileName) and (not DeleteFile(FileName)) then begin
51 // This is not a critical error, so just notify the user and continue.
52 Log('Line
{#__LINE__}: Unable delete
"'+FileName+'".');
57 // Returns the path to the common or user shell folder as specified in "Param".
58 function GetShellFolder(Param:string):string;
60 if IsAdminLoggedOn then begin
61 Param:='{common'+Param+'}';
63 Param:='{user'+Param+'}';
65 Result:=ExpandConstant(Param);
68 // As IsComponentSelected() is not supported during uninstall, this work-around
69 // simply checks the Registry. This is unreliable if the user runs the installer
70 // twice, the first time selecting the component, the second deselecting it.
71 function IsComponentInstalled(Component:String):Boolean;
73 UninstallKey,UninstallValue:String;
78 UninstallKey:='SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
{#APP_NAME}_is1
';
79 UninstallValue:='Inno Setup
: Selected Components
';
81 if RegQueryStringValue(HKEY_LOCAL_MACHINE,UninstallKey,UninstallValue,Value) then begin
82 Result:=(Pos(Component,Value)>0);
86 // Checks whether the specified directory can be created and written to
87 // by creating all intermediate directories and a temporary file.
88 function IsDirWritable(DirName:String):Boolean;
90 AbsoluteDir,FirstExistingDir,FirstCreatedDir,FileName:String;
94 AbsoluteDir:=ExpandFileName(DirName);
96 FirstExistingDir:=AbsoluteDir;
97 while not DirExists(FirstExistingDir) do begin
98 FirstCreatedDir:=FirstExistingDir;
99 FirstExistingDir:=ExtractFileDir(FirstExistingDir);
101 Log('Line
{#__LINE__}: First directory
in hierarchy that already exists
is "' + FirstExistingDir + '".')
103 if Length(FirstCreatedDir)>0 then begin
104 Log('Line
{#__LINE__}: First directory
in hierarchy needs
to be created
is "' + FirstCreatedDir + '".')
106 if ForceDirectories(DirName) then begin
107 FileName:=GenerateUniqueName(DirName,'.txt
');
108 Log('Line
{#__LINE__}: Trying
to write
to temporary
file "' + Filename + '".')
110 if SaveStringToFile(FileName,'This
file is writable
.',False) then begin
111 if not DeleteFile(FileName) then begin
121 if not DelTree(FirstCreatedDir,True,False,True) then begin
127 // Allow for custom settings to be saved to the INF file set by the /SAVEINF parameter.
128 // http://www.vincenzo.net/isxkb/index.php?title=Remembering_Custom_Page_Settings
130 LoadInfFilename,SaveInfFilename:String;
132 procedure UpdateInfFilenames;
134 LoadInfFilename:=ExpandFileName(ExpandConstant('{param:loadinf}'));
135 SaveInfFilename:=ExpandFileName(ExpandConstant('{param:saveinf}'));
138 function ShouldLoadInf:Boolean;
140 Result:=(LoadInfFilename<>'');
143 function ShouldSaveInf:Boolean;
145 Result:=(SaveInfFilename<>'');
148 function LoadInfString(Section,Key,Default:String):String;
150 Result:=GetIniString(Section,Key,Default,LoadInfFilename);
153 procedure SaveInfString(Section,Key,Value:String);
155 SetIniString(Section,Key,Value,SaveInfFilename);