]> git.lyx.org Git - lyx.git/blob - development/Win32/packaging/AltInstaller/LyXUtils.nsh
Make sure that undo is recorded when magic tricks are played with InsetBibitem.
[lyx.git] / development / Win32 / packaging / AltInstaller / LyXUtils.nsh
1 # This script contains the following functions:
2 #
3 # - LaTeXCheck (check installed LaTeX-system),
4 #    (only used by Small and Complete installer), uses:
5 #    StrPointer
6 #    StrPoint
7 #    RevStrPointer
8 #    RevStrPoint
9 #
10 # - un.DelAppPathSub and UnAppPreSuff,
11 #    (delete the folder ~\Documents and Settings\username\Application Data\LyX for all users), uses:
12 #    un.GetParentA
13 #    un.GetUsers
14 #    un.StrPoint
15 #    StrPointer
16 #    StrPoint
17 #    UnAppPreSuff
18 #
19 # - CreateAppPathSub and AppPreSuff,
20 #    (creates the folder ~\Documents and Settings\username\Application Data\LyX for all users),
21 #    (only used by Small and Complete installer), uses:
22 #    GetParentA
23 #    GetUsers
24 #    StrPointer
25 #    StrPoint
26 #    UnAppPreSuff
27 #
28 # - CheckAppPathPreferences (replaces the old install folder name with the new one in the preferences files)
29 #                           (used by Update installer), uses:
30 #    ReplaceLineContent
31 #
32 # - IsUserAdmin (checks if user is admin)
33 #
34 # - FileCheck (checks if a given file exists)
35 #
36 #--------------------------
37
38 !macro StrPointer FindStr SearchStr Pointer
39  # searches for a string/character (SearchStr) in another string (FindStr)
40  # and returns the number of the character in the FindStr where the SearchStr was found (Pointer)
41  # if nothing was found or the search is impossible the Pointer is set to -1
42  
43  StrLen $R2 ${SearchStr}
44  StrLen $R4 ${FindStr}
45  StrCpy $R5 0
46  ${if} $R2 == 0
47  ${orif} $R4 == 0
48   Goto NotFound
49  ${endif}
50  IntCmp $R4 $R2 loopA NotFound
51  loopA:
52   StrCpy $R3 ${FindStr} $R2 $R5
53   StrCmp $R3 ${SearchStr} Found
54   IntOp $R5 $R5 + 1
55   IntCmp $R4 $R5 loopA NotFound
56   Goto loopA
57  Found:
58   StrCpy ${Pointer} $R5
59   Goto done
60  NotFound:
61   StrCpy ${Pointer} "-1"
62  done:
63
64 !macroend
65  
66 #--------------------------------
67
68 Function StrPoint
69  !insertmacro StrPointer $String $Search $Pointer
70 FunctionEnd
71
72 #--------------------------------
73
74 !macro RevStrPointer FindStr SearchStr Pointer
75  # searches for a string/character (SearchStr) in another string (FindStr) in reverse order
76  # and returns the number of the character in the FindStr where the SearchStr was found (Pointer)
77  # if nothing was found or the search is impossible the Pointer is set to +1
78  
79  StrLen $R2 ${SearchStr}
80  StrLen $R4 ${FindStr}
81  ${if} $R2 == 0
82  ${orif} $R4 == 0
83   Goto NotFound
84  ${endif}
85  IntCmp $R4 $R2 loopA NotFound
86  StrCpy $R5 "-$R2"
87  loopA:
88   StrCpy $R3 ${FindStr} $R2 $R5
89   StrCmp $R3 ${SearchStr} Found
90   IntOp $R5 $R5 - 1
91   IntCmp "$R5" "-$R4" loopA NotFound
92   Goto loopA
93  Found:
94   StrCpy ${Pointer} $R5
95   Goto done
96  NotFound:
97   StrCpy ${Pointer} "+1"
98  done:
99
100 !macroend
101  
102 #--------------------------------
103
104 !if ${INSTALLER_TYPE} == "NotUpdate" # only for Small and Complete installer
105
106  Function RevStrPoint
107   !insertmacro RevStrPointer $String $Search $Pointer
108  FunctionEnd
109
110 !endif # endif ${INSTALLER_TYPE} == "NotUpdate"
111
112 #--------------------------------
113
114 !macro AppPreSuff AppPre AppSuff
115  # the APPDATA path for a local user has for WinXP and 2000 the following structure:
116  # C:\Documents and Settings\username\Application Data
117  # for Win Vista the structure is:
118  # C:\Users\username\AppData\Roaming
119  # this macro saves the "C:\Documents and Settings\" substring into the variable "AppPre"
120  # and the "Application Data" substring into the variable "AppSuff"
121   
122   # switch temporarily to local user because the all users application data path is in
123   # Vista only C:\ProgramData 
124   SetShellVarContext current
125   StrCpy $String "$APPDATA"
126   Var /GLOBAL APPDATemp
127   StrCpy $APPDATemp "$APPDATA"
128   ${if} $ProductRootKey == "HKLM"
129    SetShellVarContext all # move back to all users
130   ${endif}
131   StrCpy $Search "\"
132   Call StrPoint # search for the first "\"
133   IntOp $Pointer $Pointer + 1 # jump after the "\"
134   StrCpy $String $String "" $Pointer # cut off the part before the first "\"
135   StrCpy $0 $Pointer
136   Call StrPoint # search for the second "\"
137   IntOp $0 $0 + $Pointer # $0 is now the pointer to the second "\" in the APPDATA string
138   StrCpy ${AppPre} $APPDATemp $0 # save the part before the second "\"
139   IntOp $Pointer $Pointer + 1 # jump after the "\"
140   StrCpy $String $String "" $Pointer # cut off the part before the second "\"
141   Call StrPoint # search for the third "\"
142   IntOp $Pointer $Pointer + 1 # jump after the "\"
143   StrCpy ${AppSuff} $String "" $Pointer # save the part after the third "\"
144
145 !macroend
146
147 #--------------------------------
148
149 Function GetParentA
150  # deletes a subfolder of the APPDATA path for all users
151  # used by the function "un.getUsers"
152
153   Exch $R0
154   Push $R1
155   Push $R2
156   Push $R3
157   StrCpy $R1 0
158   StrLen $R2 $R0
159   loop:
160    IntOp $R1 $R1 + 1
161    IntCmp $R1 $R2 get 0 get
162    StrCpy $R3 $R0 1 -$R1
163    StrCmp $R3 "\" get
164   Goto loop
165   get:
166    StrCpy $R0 $R0 -$R1
167    Pop $R3
168    Pop $R2
169    Pop $R1
170    Exch $R0
171    
172 FunctionEnd
173
174 #--------------------------------
175
176 Function GetUsers
177  # reads the subfolders of the "Documents and Settings" folder to get a list of the users
178
179   StrCpy $R3 ""
180   Push "$PROFILE"
181   Call GetParentA  
182   Pop $R2
183   StrCpy $R2 "$R2"
184   FindFirst $R0 $R1 "$R2\*"
185   StrCmp $R1 "" findend 0
186   findloop:
187    IfFileExists "$R2\$R1\*.*" 0 notDir
188    StrCmp $R1 "." notDir
189    StrCmp $R1 ".." notDir
190    StrCmp $R1 "All Users" notDir
191    StrCmp $R1 "Default User" notDir
192    StrCmp $R1 "All Users.WINNT" notDir
193    StrCmp $R1 "Default User.WINNT" notDir  
194   StrCpy $R3 "$R3|$R1"
195   notDir:
196    FindNext $R0 $R1
197    StrCmp $R1 "" findend 0
198   Goto findloop
199   findend:
200    FindClose $R0
201   
202 FunctionEnd
203
204 #--------------------------------
205
206 Function un.GetParentA
207  # deletes a subfolder of the APPDATA path for all users
208  # used by the function "un.getUsers"
209
210   Exch $R0
211   Push $R1
212   Push $R2
213   Push $R3
214   StrCpy $R1 0
215   StrLen $R2 $R0
216   loop:
217    IntOp $R1 $R1 + 1
218    IntCmp $R1 $R2 get 0 get
219    StrCpy $R3 $R0 1 -$R1
220    StrCmp $R3 "\" get
221   Goto loop
222   get:
223    StrCpy $R0 $R0 -$R1
224    Pop $R3
225    Pop $R2
226    Pop $R1
227    Exch $R0
228    
229 FunctionEnd
230
231 #--------------------------------
232
233 Function un.GetUsers
234  # reads the subfolders of the "Documents and Settings" folder to get a list of the users
235
236   StrCpy $R3 ""
237   Push "$PROFILE"
238   Call un.GetParentA  
239   Pop $R2
240   StrCpy $R2 "$R2"
241   FindFirst $R0 $R1 "$R2\*"
242   StrCmp $R1 "" findend 0
243   findloop:
244    IfFileExists "$R2\$R1\*.*" 0 notDir
245    StrCmp $R1 "." notDir
246    StrCmp $R1 ".." notDir
247    StrCmp $R1 "All Users" notDir
248    StrCmp $R1 "Default User" notDir
249    StrCmp $R1 "All Users.WINNT" notDir
250    StrCmp $R1 "Default User.WINNT" notDir  
251   StrCpy $R3 "$R3|$R1"
252   notDir:
253    FindNext $R0 $R1
254    StrCmp $R1 "" findend 0
255   Goto findloop
256   findend:
257    FindClose $R0
258   
259 FunctionEnd
260
261 #--------------------------------
262
263 Function un.StrPoint
264  !insertmacro StrPointer $String $Search $Pointer
265 FunctionEnd
266
267 #--------------------------------
268
269 !macro UnAppPreSuff AppPre AppSuff
270  # the APPDATA path for a local user has for WinXP and 2000 the following structure:
271  # C:\Documents and Settings\username\Application Data
272  # for Win Vista the structure is:
273  # C:\Users\username\AppData\Roaming
274  # this macro saves the "C:\Documents and Settings\" substring into the variable "AppPre"
275  # and the "Application Data" substring into the variable "AppSuff"
276   
277   SetShellVarContext current # switch temoprarily to local user
278   StrCpy $String "$APPDATA"
279   StrCpy $APPDATemp "$APPDATA"
280   ${if} $Answer == "yes" # then user has admin priviledges
281    SetShellVarContext all # move back to all users
282   ${endif}
283   StrCpy $Search "\"
284   Call un.StrPoint # search for the first "\"
285   IntOp $Pointer $Pointer + 1 # jump after the "\"
286   StrCpy $String $String "" $Pointer # cut off the part before the first "\"
287   StrCpy $0 $Pointer
288   Call un.StrPoint # search for the second "\"
289   IntOp $0 $0 + $Pointer # $0 is now the pointer to the second "\" in the APPDATA string
290   StrCpy ${AppPre} $APPDATemp $0 # save the part before the second "\"
291   IntOp $Pointer $Pointer + 1 # jump after the "\"
292   StrCpy $String $String "" $Pointer # cut off the part before the second "\"
293   Call un.StrPoint # search for the third "\"
294   IntOp $Pointer $Pointer + 1 # jump after the "\"
295   StrCpy ${AppSuff} $String "" $Pointer # save the part after the third "\"
296
297 !macroend
298
299 #--------------------------------
300
301 Function un.DelAppPathSub
302  # deletes a subfolder of the APPDATA path for all users
303
304   # get list of all users
305   Push $R0
306   Push $R1
307   Push $R2
308   Push $R3
309   Call un.GetUsers
310   StrCpy $UserList $R3 "" 1 # cut off the "|" at the end of the list
311   Pop $R3
312   Pop $R2
313   Pop $R1
314   Pop $R0
315   
316   # the usernames in the list of all users is separated by "|"
317   loop:
318    StrCpy $String "$UserList"
319    StrCpy $Search "|"
320    Call un.StrPoint # search for the "|"
321    StrCmp $Pointer "-1" ready
322    StrCpy $0 $UserList $Pointer # $0 contains now the username
323    IntOp $Pointer $Pointer + 1 # jump after the "|"
324    StrCpy $UserList $UserList "" $Pointer # cut off the first username in the list
325    # generate the string for the current user
326    # AppPre and AppSuff are generated in the macro "AppPreSuff"
327    RMDir /r "$AppPre\$0\$AppSuff\$AppSubfolder" # delete the folder
328   Goto loop
329   ready:
330   StrCpy $0 $UserList
331   RMDir /r "$AppPre\$0\$AppSuff\$AppSubfolder" # delete the folder
332   
333 FunctionEnd
334
335 #--------------------------------
336
337 !if ${INSTALLER_TYPE} == "NotUpdate" # only for Small and Complete installer
338
339  Function CreateAppPathSub
340  # creates a subfolder of the APPDATA path for all users
341
342   # get folder names
343   !insertmacro AppPreSuff $AppPre $AppSuff
344
345   # get list of all users
346   Push $R0
347   Push $R1
348   Push $R2
349   Push $R3
350   Call GetUsers
351   StrCpy $UserList $R3 "" 1 # cut off the "|" at the end of the list
352   Pop $R3
353   Pop $R2
354   Pop $R1
355   Pop $R0
356   
357   # the usernames in the list of all users is separated by "|"
358   loop:
359    StrCpy $String "$UserList"
360    StrCpy $Search "|"
361    Call StrPoint # search for the "|"
362    StrCmp $Pointer "-1" ready # the loop is finished when no "|" could be found
363    StrCpy $0 $UserList $Pointer # $0 contains now the username
364    IntOp $Pointer $Pointer + 1 # jump after the "|"
365    StrCpy $UserList $UserList "" $Pointer # cut off the first username in the list
366    # generate the string for the current user
367    # AppPre and AppSuff are generated in the macro "AppPreSuff"
368    CreateDirectory "$AppPre\$0\$AppSuff\$AppSubfolder" # create the folder
369    CopyFiles "$AppFiles" "$AppPre\$0\$AppSuff\$AppSubfolder"
370   Goto loop
371   ready:
372   # now do the same for the last user name
373   StrCpy $0 $UserList
374   CreateDirectory "$AppPre\$0\$AppSuff\$AppSubfolder" # create the folder
375   CopyFiles "$AppFiles" "$AppPre\$0\$AppSuff\$AppSubfolder"
376   
377  FunctionEnd
378
379 !endif # endif ${INSTALLER_TYPE} == "NotUpdate"
380
381 #--------------------------------
382
383 !if ${INSTALLER_TYPE} == "Update" # only for Update installer
384
385  Function ReplaceLineContent
386  # replaces "$OldString" with "LyX $NewString"
387
388   ${WordReplace} '$R9' "$OldString" "$NewString" "+" '$R9' # macro from WordFunc.nsh
389   Push $0
390  
391  FunctionEnd
392
393 !endif # endif ${INSTALLER_TYPE} == "Update"
394
395 #--------------------------------
396
397 !if ${INSTALLER_TYPE} == "Update" # only for Update installer
398
399  Function CheckAppPathPreferences
400  # replaces a string "$OldString" with "$NewString" in a file "$FileName"
401
402   # get folder names
403   !insertmacro AppPreSuff $AppPre $AppSuff
404
405   # get list of all users
406   Push $R0
407   Push $R1
408   Push $R2
409   Push $R3
410   Call GetUsers
411   StrCpy $UserList $R3 "" 1 # cut off the "|" at the end of the list
412   Pop $R3
413   Pop $R2
414   Pop $R1
415   Pop $R0
416   
417   # the usernames in the list of all users is separated by "|"
418   loopPrefs:
419    StrCpy $String "$UserList"
420    StrCpy $Search "|"
421    Call StrPoint # search for the "|"
422    StrCmp $Pointer "-1" ready # the loop is finished when no "|" could be found
423    StrCpy $0 $UserList $Pointer # $0 contains now the username
424    IntOp $Pointer $Pointer + 1 # jump after the "|"
425    StrCpy $UserList $UserList "" $Pointer # cut off the first username in the list
426    # generate the string for the current user
427    # AppPre and AppSuff are generated in the macro "AppPreSuff"
428    StrCpy $AppPath "$AppPre\$0\$AppSuff\$AppSubfolder"
429    # read the preferences file to test if it exists
430    FileOpen $R1 "$AppPath\$FileName" r
431    IfErrors doneA
432    FileClose $R1
433    # search for "$OldString" and replace it with "$NewString"
434    ${LineFind} "$AppPath\$FileName" "" "1:-1" "ReplaceLineContent" # macro from TextFunc.nsh # calls Function ReplaceLineContent
435    doneA:
436   Goto loopPrefs
437   ready:
438   # now do the same for the last user name
439   StrCpy $0 $UserList
440   StrCpy $AppPath "$AppPre\$0\$AppSuff\$AppSubfolder"
441   FileOpen $R1 "$AppPath\$FileName" r
442   IfErrors doneB
443   FileClose $R1
444   ${LineFind} "$AppPath\$FileName" "" "1:-1" "ReplaceLineContent"
445   doneB:
446   
447  FunctionEnd
448
449 !endif # endif ${INSTALLER_TYPE} == "Update"
450
451 #--------------------------------
452
453 !macro IsUserAdmin Result Name
454
455  ClearErrors
456  UserInfo::GetName
457  IfErrors Win9x
458  Pop $0
459  StrCpy ${Name} $0
460  UserInfo::GetAccountType
461  Pop $1
462  ${if} $1 == "Admin"
463   StrCpy ${Result} "yes"
464  ${else}
465   StrCpy ${Result} "no"
466  ${endif}
467  Goto done
468
469  Win9x:
470   StrCpy ${Result} "yes"
471  done:
472
473 !macroend
474
475 #--------------------------------
476
477 !macro FileCheck Result FileName FilePath
478  # checks if a file exists, returns "True" or "False"
479
480  Push $0
481  Push $1
482  StrCpy $0 ""
483  StrCpy $1 ""
484  FileOpen $0 "${Filepath}\${FileName}" r
485  ${if} $0 = ""
486   StrCpy $1 "False"
487  ${Else}
488   StrCpy $1 "True"
489  ${endif}
490  FileClose $0
491  StrCpy ${Result} $1
492  Pop $1
493  Pop $0
494
495 !macroend
496
497 #------------------------------------------
498
499 !if ${INSTALLER_TYPE} == "NotUpdate" # only for Small and Complete installer
500
501  Function LaTeXCheck
502  # searches the string "$Search" in the string "$String" and extracts the path around it
503  # the extracted path is checked if the file "latex.exe" is in it
504
505    StartCheck:
506    StrLen $3 $String
507    Call StrPoint
508    ${if} $Pointer == "-1" # if nothing was found
509     StrCpy $LatexPath ""
510     Return
511    ${endif}
512    IntOp $3 $3 - $Pointer
513    StrCpy $4 $String $3 "-$3" # $4 is now the part behind the $Search string
514    StrCpy $String $String $Pointer # $String is now the part before the $Search string
515    StrCpy $Search ":" # search for the ":" after the first previous drive letter
516    Call RevStrPoint
517    IntOp $Pointer $Pointer - 1 # jump before the ":" to the drive letter
518    StrCpy $Pointer $Pointer "" 1 # cut of the "-" sign
519    StrCpy $LatexPath $String $Pointer "-$Pointer"
520    StrCpy $String $4
521    StrCpy $Search ";" # search for the following ";" that separates the different paths
522    Call StrPoint
523    ${if} $Pointer != "-1" # if something was found
524     StrCpy $String $String $Pointer
525    ${endif}
526    StrCpy $LatexPath "$LatexPath$String"
527    # check if the latex.exe exists in the $LatexPath folder
528    !insertmacro FileCheck $5 "latex.exe" "$LatexPath"
529    ${if} $5 == "False" # delete the entry with the wrong path to the latex.exe and try again
530     StrCpy $LatexPath ""
531     StrLen $3 $String
532     StrCpy $String $4 "" $3
533     ${if} $2 == "TeXLive"
534      StrCpy $Search "TeXLive"
535     ${else}
536      StrCpy $Search "miktex"
537     ${endif}
538     Goto StartCheck
539    ${endif}
540
541  FunctionEnd
542
543 !endif # endif ${INSTALLER_TYPE} == "NotUpdate"
544