1 Option Explicit ' Variables must be declared explicitly
5 '******************************************************************************
7 '******************************************************************************
9 const Version = "2.10.5.20050325"
10 const Installer = "cc65 Installer"
11 const SpaceNeeded = 20 ' Free space needed on drive in MB
12 const Shortcut = true ' Create shortcut on desktop
16 '******************************************************************************
18 '******************************************************************************
19 const SysEnv = "HKLM\System\CurrentControlSet\Control\Session Manager\Environment"
20 const SysPath = "HKLM\System\CurrentControlSet\Control\Session Manager\Environment\Path"
24 '******************************************************************************
26 '******************************************************************************
27 dim Tab, NewLine ' String constants
28 dim Shell, FSO ' Global objects
29 dim ProgArgs ' Program arguments
30 dim Dbg ' Output debugging stuff
31 dim Language ' Program language
32 dim SystemDrive ' The system drive
33 dim SystemRoot ' The windows directory
34 dim UserName ' Name if the current user
35 dim UserProfile ' User profile directory
36 dim ProgramFiles ' Program files directory
37 dim AppData ' Application data directory
38 dim InstallSource ' Installation source directory
39 dim InstallTarget ' Installation target directory
40 dim UninstallCtrlFileName ' Name of the control file for the uninstaller
41 dim UninstallCtrlFile ' Control file for the uninstaller
42 dim Uninstaller ' Path to the uninstaller file
43 dim UninstallerCmdLine ' Command line for the uninstaller
44 dim Programs ' "Programs" menu folder
45 dim Desktop ' "Desktop" menu folder
46 dim RegUninstall ' Registry key for uninstall entries
47 dim BinDir ' Directory for binaries
48 dim LibDir ' Library directory
49 dim IncDir ' Include directory
50 dim DocIndexFile ' Name of documentation index file
51 dim AnnouncementFile ' Name of the announcement file
55 '******************************************************************************
56 ' Display an error message window with an OK button
57 '******************************************************************************
59 call MsgBox (Msg, vbOkOnly + vbExclamation, Installer)
64 '******************************************************************************
65 ' Display an error message window and abort the installer
66 '******************************************************************************
74 '******************************************************************************
75 ' Display a message with an OK button
76 '******************************************************************************
78 call MsgBox (Msg, vbOkOnly + vbInformation, Installer)
83 '******************************************************************************
84 ' Convert a number to a string
85 '******************************************************************************
86 function ToString (Num)
87 ToString = FormatNumber (Num, vbFalse, vbTrue, vbFalse, vbFalse)
92 '******************************************************************************
93 ' Return a message in the current language
94 '******************************************************************************
98 ' Handle other languages here
101 if IsEmpty (Msg) then
102 ' No assignment, use english
105 Msg = "Installation was aborted."
107 Msg = "You must be Administrator to install %1."
108 Msg = Msg & " Are you sure you want to continue?"
110 Msg = "Cannot copy %1 to %2: " & NewLine & "%3"
112 Msg = "%1 does not exist." & NewLine & "Create it?"
114 Msg = "Cannot create %1:" & NewLine & "%2"
116 Msg = "Cannot delete %1:" & NewLine & "%2"
117 case "MSG_DRIVESPACE"
118 Msg = "Not enough space left on drive %1" & NewLine
119 Msg = Msg & "At least %2 MB are needed."
120 case "MSG_INSTALLPATH"
121 Msg = "The package will be installed in %1"
123 Msg = "%1 Documentation"
124 case "MSG_REGREADERR"
125 Msg = "Installation failed: Cannot read the registry!"
126 case "MSG_REGWRITEERR"
127 Msg = "Installation failed: Cannot write to the registry!"
128 case "MSG_REMOVEENTRY"
131 Msg = "A folder with the name %1 does already exist."
132 Msg = Msg & " Is it ok to remove the folder?"
134 Msg = "Found an old version. Remove it?"
136 Msg = "Installation was successful!"
137 case "MSG_UNINSTALLERR"
138 Msg = "There was a problem uninstalling the old version. Please"
139 Msg = Msg & " uninstall the old program manually and restart"
140 Msg = Msg & " the installation."
141 case "MSG_ANNOUNCEMENT"
142 Msg = "cc65 Announcement"
143 case "MSG_INCOMPLETE"
144 Msg = "The package seems to be incomplete and cannot be"
145 Msg = Msg & " installed."
155 '******************************************************************************
156 ' Format a string replacing %n specifiers in the format string F
157 '******************************************************************************
158 function Fmt (F, Values)
159 dim I, Count, Key, Val, Start, Pos
160 Count = UBound (Values) ' How many values?
161 for I = Count to 0 step -1
162 Key = "%" & ToString (I)
163 select case VarType (Values (I))
167 Val = ToString (Values (I))
169 Val = ToString (Values (I))
173 Val = ToString (Values (I))
175 Val = ToString (Values (I))
179 Abort ("Internal error: Invalid conversion in Format()")
181 F = Replace (F, Key, Val)
188 '******************************************************************************
189 ' Format a message replacing %n specifiers in the format string F
190 '******************************************************************************
191 function FmtMsg (Msg, Values)
192 FmtMsg = Fmt (GetMsg (Msg), Values)
197 '******************************************************************************
198 ' Return an environment string. Fix up Microsofts "innovative" ideas.
199 '******************************************************************************
200 function GetEnv (Key)
202 Value = Shell.ExpandEnvironmentStrings (Key)
204 GetEnv = vbNullString
212 '******************************************************************************
213 ' Build a path from two components
214 '******************************************************************************
215 function BuildPath (Path, Name)
216 BuildPath = FSO.BuildPath (Path, Name)
221 '******************************************************************************
222 ' Return true if the file with the given name exists
223 '******************************************************************************
224 function FileExists (Name)
226 FileExists = FSO.FileExists (Name)
231 '******************************************************************************
232 ' Return true if the folder with the given name exists
233 '******************************************************************************
234 function FolderExists (Name)
236 FolderExists = FSO.FolderExists (Name)
241 '******************************************************************************
242 ' Copy a file and return an error message (empty string if no error)
243 '******************************************************************************
244 function CopyFile (Source, Target)
245 if Right (Target, 1) <> "\" and FolderExists (Target) then
246 Target = Target & "\"
249 call FSO.CopyFile (Source, Target)
251 CopyFile = Err.Description
256 '******************************************************************************
257 ' Create a folder and all parent folders and return an error string
258 '******************************************************************************
259 function CreateFolder (Path)
261 ' If the parent folder does not exist, try to create it
263 ParentFolder = FSO.GetParentFolderName (Path)
264 if ParentFolder <> "" and not FolderExists (ParentFolder) then
265 CreateFolder (ParentFolder)
268 ' Now try to create the actual folder
270 FSO.CreateFolder (Path)
271 CreateFolder = Err.Description
277 '******************************************************************************
278 ' Delete a file and return an error string
279 '******************************************************************************
280 function DeleteFile (Name)
282 call FSO.DeleteFile (Name, true)
283 DeleteFile = Err.Description
288 '******************************************************************************
289 ' Delete a folder and return an error string
290 '******************************************************************************
291 function DeleteFolder (Path)
293 call FSO.DeleteFolder (Path, true)
294 DeleteFolder = Err.Description
299 '******************************************************************************
300 ' Return the type of a registry entry
301 '******************************************************************************
302 function RegType (Value)
306 ' Determine the type of the registry value. If the string contains percent
307 ' signs, use REG_EXPAND_SZ, otherwise use REG_SZ. This isn't always safe,
308 ' but there is no way to determine the type, and VBS itself is too stupid
309 ' to choose the correct type itself. Add the usual curse over Microsoft
311 Result = InStr (1, Value, "%")
315 RegType = "REG_EXPAND_SZ"
321 '******************************************************************************
322 ' Read a string from the registry. Return an empty string if nothing was found.
323 '******************************************************************************
324 function RegReadStr (Key)
326 RegReadStr = Shell.RegRead (Key)
327 if Err.Number <> 0 then
334 '******************************************************************************
335 ' Write a binary value to the registry, return an error description
336 '******************************************************************************
337 function RegWriteBin (Key, Value)
339 Shell.RegWrite Key, Value, "REG_BINARY"
340 RegWriteBin = Err.Description
342 WriteUninstallCtrlFile ("R " & Key)
347 '******************************************************************************
348 ' Write a string value to the registry, return an error description
349 '******************************************************************************
350 function RegWriteStr (Key, Value)
352 Shell.RegWrite Key, Value, "REG_SZ"
353 RegWriteStr = Err.Description
355 WriteUninstallCtrlFile ("R " & Key)
360 '******************************************************************************
361 ' Run a program, wait for its termination and return an error code.
362 '******************************************************************************
363 function Run (Cmd, WinState)
367 ErrCode = Shell.Run (Cmd, WinState, true)
368 if Err.Number <> 0 then
376 '******************************************************************************
377 ' Display a progress bar using the internet exploder
378 '******************************************************************************
379 dim PBDoc ' Progress bar document object
380 dim PBVal ' Current progress bar setting
381 dim IEApp ' Internet exploder application object
386 sub ProgressBar (Percent)
388 ' Remember the last setting
391 'Create the progress bar window
392 if PBDoc is nothing then
394 if ((Cint (Percent) < 0) or (Cint (Percent) > 100)) then
395 ' Close request, but object already destroyed
399 ' Create an object that control the internet exploder
400 set IEApp = CreateObject ("InternetExplorer.Application")
402 ' Set the exploder to fullscreen and retrieve its size
403 dim ScreenHeight, ScreenWidth
404 IEApp.Visible = false
405 IEApp.FullScreen = true
406 ScreenWidth = IEApp.Width
407 ScreenHeight = IEApp.Height
408 IEApp.FullScreen = false
410 ' Now prepare the actual window
412 IEApp.AddressBar = false
415 IEApp.MenuBar = false
416 IEApp.StatusBar = false
418 IEApp.ToolBar = false
419 IEApp.Resizable = false
420 IEApp.Left = (ScreenWidth - IEApp.Width) / 2
421 IEApp.Top = (ScreenHeight - IEApp.Height) / 2
422 call IEApp.Navigate ("about:blank")
424 call WScript.Sleep (100)
427 ' Connect to the displayed document
428 do until not PBDoc is nothing
429 call WScript.Sleep (100)
430 set PBDoc = IEApp.Document
433 ' Generate a new document showing a progress bar
435 call PBDoc.Write ("<html><head><title>" & Installer & " progress</title></head>")
436 call PBDoc.Write ("<body bgcolor=#C0C0C0><center>")
437 call PBDoc.Write ("<table width=100% border=1 frame=box><tr><td>")
438 call PBDoc.Write ("<table id=progress width=0 border=0 cellpadding=0 cellspacing=0 bgcolor=#FFFFFF>")
439 call PBDoc.Write ("<tr><td> </td></tr></table>")
440 call PBDoc.Write ("</td></tr></table>")
441 call PBDoc.Write ("</center></body></html>")
444 ' Display the exploder window
448 if ((Cint (Percent) < 0) or (Cint (Percent) > 100)) then
449 ' Request for shutdown
450 IEApp.Visible = false
455 ' Update the progress bar
456 if Cint (Percent) = 0 then
457 PBDoc.all.progress.width = "1%"
458 PBDoc.all.progress.bgcolor = "#C0C0C0"
460 PBDoc.all.progress.width = Cstr (Cint (Percent)) & "%"
461 PBDoc.all.progress.bgcolor = "#0000C0"
469 '******************************************************************************
470 ' Initialize global variables
471 '******************************************************************************
472 sub InitializeGlobals ()
475 ' String stuff used for formatting
480 set Shell = WScript.CreateObject ("WScript.Shell")
481 set FSO = CreateObject ("Scripting.FileSystemObject")
484 set ProgArgs = WScript.Arguments
486 ' Handle program arguments
489 for I = 0 to ProgArgs.Count-1
490 select case ProgArgs(I)
500 ' Paths and locations
501 SystemDrive = GetEnv ("%SystemDrive%")
502 if SystemDrive = vbNullString then
505 SystemRoot = GetEnv ("%SystemRoot%")
506 if SystemRoot = vbNullString then
507 SystemRoot = BuildPath (SystemDrive, "winnt")
509 UserName = GetEnv ("%USERNAME%")
510 if UserName = vbNullString then
511 UserName = "Administrator"
513 UserProfile = GetEnv ("%USERPROFILE%")
514 if UserProfile = vbNullString then
515 UserProfile = BuildPath (SystemDrive, "Dokumente und Einstellungen\" & UserName)
517 ProgramFiles = GetEnv ("%ProgramFiles%")
518 if ProgramFiles = vbNullString then
519 ProgramFiles = BuildPath (SystemDrive, "Programme")
521 AppData = GetEnv ("%AppData%")
522 if AppData = vbNullString then
523 AppData = UserProfile
525 InstallSource = FSO.GetParentFolderName (WScript.ScriptFullName)
526 InstallTarget = BuildPath (ProgramFiles, AppName)
528 Programs = Shell.SpecialFolders ("AllUsersPrograms")
529 Desktop = Shell.SpecialFolders ("AllUsersDesktop")
532 set UninstallCtrlFile = nothing
533 Uninstaller = BuildPath (InstallTarget, "uninstall.vbs")
534 UninstallCtrlFileName = BuildPath (InstallTarget, "uninstall.lst")
535 UninstallerCmdLine = "-" & Language & " " & AppName & " " & UninstallCtrlFileName
538 RegUninstall = "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\" & AppName & "\"
541 BinDir = BuildPath (InstallTarget, "bin")
542 LibDir = BuildPath (InstallTarget, "lib")
543 IncDir = BuildPath (InstallTarget, "include")
546 AnnouncementFile = "announce.txt"
547 DocIndexFile = "doc\index.html"
552 '******************************************************************************
553 ' Ask a yes/no question and return the result. "Yes" is default.
554 '******************************************************************************
555 function AskYesNo (Question)
556 AskYesNo = MsgBox (Question, vbYesNo + vbQuestion + vbDefaultButton1, Installer)
561 '******************************************************************************
562 ' Ask a yes/no question and return the result. "No" is default.
563 '******************************************************************************
564 function AskNoYes (Question)
565 AskNoYes = MsgBox (Question, vbYesNo + vbQuestion + vbDefaultButton2, Installer)
570 '******************************************************************************
571 ' Tell the user that the installation was aborted and terminate the script
572 '******************************************************************************
574 call MsgBox (GetMsg ("MSG_ABORTINFO"), vbOkOnly + vbInformation, Installer)
580 '******************************************************************************
581 ' Input routine with the window caption preset
582 '******************************************************************************
583 function Input (Prompt, Default)
584 Input = InputBox (Prompt, Installer, Default)
589 '******************************************************************************
590 ' Check if a directory is a given the path
591 '******************************************************************************
592 function DirInPath (ByVal Dir)
596 ' Get the path in lower case
597 Path = LCase (GetEnv ("%Path%"))
599 ' Convert the directory to lower case
602 ' Split the path into separate entries
603 Entries = Split (Path, ";")
606 for I = LBound (Entries) to UBound (Entries)
607 if Entries(I) = Dir then
619 '******************************************************************************
620 ' Function that displays the paths and locations found
621 '******************************************************************************
622 function OneLoc (Key, Value)
625 if Len (Result) <= 8 then
626 Result = Result & Tab
628 OneLoc = Result & Tab & "=" & Tab & Value & NewLine
631 sub ShowPathsAndLocations ()
633 Msg = Msg & OneLoc ("SystemDrive", SystemDrive)
634 Msg = Msg & OneLoc ("SystemRoot", SystemRoot)
635 Msg = Msg & OneLoc ("UserName", UserName)
636 Msg = Msg & OneLoc ("UserProfile", UserProfile)
637 Msg = Msg & OneLoc ("ProgramFiles", ProgramFiles)
638 Msg = Msg & OneLoc ("AppData", AppData)
639 Msg = Msg & OneLoc ("InstallSource", InstallSource)
640 Msg = Msg & OneLoc ("InstallTarget", InstallTarget)
641 Msg = Msg & OneLoc ("Programs", Programs)
642 Msg = Msg & OneLoc ("Desktop", Desktop)
643 Msg = Msg & OneLoc ("Free space", ToString (GetDriveSpace (InstallTarget)))
645 call MsgBox (Msg, vbOkOnly, "Paths and Locations")
650 '******************************************************************************
651 ' Return the amount of free space for a path (in Megabytes)
652 '******************************************************************************
653 function GetDriveSpace (Path)
656 set Drive = FSO.GetDrive (FSO.GetDriveName (Path))
657 if Err.Number <> 0 then
660 GetDriveSpace = Drive.FreeSpace / (1024 * 1024)
666 '******************************************************************************
667 ' Check that there's something to install
668 '******************************************************************************
669 sub CheckFilesToInstall ()
671 ' If the uninstaller is unavailable for some reason or the other, we
672 ' have a problem, because the installer will create an uninstaller entry
673 ' in the registry, but it will not work, which means that the package
674 ' cannot be deinstalled or overwritten. So we have to check that at least
675 ' the uninstaller is available in the same directory as the installer.
676 if not FileExists (BuildPath (InstallSource, "uninstall.vbs")) then
677 Abort (GetMsg ("MSG_INCOMPLETE"))
683 '******************************************************************************
684 ' Check that were running this script as admin
685 '******************************************************************************
686 sub CheckAdminRights ()
688 ' FIXME: This check is not perfect
689 if UserName <> "Administrator" then
693 if AskNoYes (FmtMsg ("MSG_ADMIN", Args)) <> vbYes then
702 '******************************************************************************
703 ' Remove an old installation.
704 '******************************************************************************
705 sub RemoveOldInstall (UninstallCmd)
709 ' Execute the uninstall
710 ErrCode = Run (UninstallCmd, 0)
712 ' Tell the user that the uninstall is done
714 call Abort (GetMsg ("MSG_UNINSTALLERR"))
720 '******************************************************************************
721 ' Check if there is an old installation. Offer to remove it.
722 '******************************************************************************
723 sub CheckOldInstall ()
727 ' Read the uninstall command from the registry
728 UninstallCmd = RegReadStr (RegUninstall & "UninstallString")
730 ' Check if there is already an executable
731 if UninstallCmd <> "" then
733 ' Ask to remove an old install
734 if AskYesNo (GetMsg ("MSG_REMOVEOLD")) = vbYes then
735 ' Remove the old installation
736 call RemoveOldInstall (UninstallCmd)
745 '******************************************************************************
746 ' Check that the install target exists. Offer to create it.
747 '******************************************************************************
748 sub CheckInstallTarget ()
750 dim Msg, Result, Args(2)
752 ' Tell the user about the install target and ask if it's ok
753 Args(1) = InstallTarget
754 Msg = FmtMsg ("MSG_INSTALLPATH", Args)
755 if MsgBox (Msg, vbOkCancel, Installer) <> vbOk then
759 ' Check if there's enough space left on the target drive
760 if GetDriveSpace (InstallTarget) < SpaceNeeded then
761 Args(1) = FSO.GetDriveName (InstallTarget)
762 Args(2) = SpaceNeeded
763 call Abort (FmtMsg ("MSG_DRIVESPACE", Args))
766 ' Check if the install path exist, create it if necessary
767 if not FolderExists (InstallTarget) then
768 Result = CreateFolder (InstallTarget)
770 Args(1) = InstallTarget
772 call Abort (FmtMsg ("MSG_CREATEERR", Args))
780 '******************************************************************************
781 ' Create the uninstall control file
782 '******************************************************************************
783 sub CreateUninstallCtrlFile ()
787 ' Generate the filename
789 set UninstallCtrlFile = FSO.CreateTextFile (UninstallCtrlFileName, true)
791 if Err.Number <> 0 then
793 Args(1) = UninstallCtrlFileName
794 Args(2) = Err.Description
795 call ErrorMsg (FmtMsg ("MSG_CREATEERR", Args))
799 ' Write the name of the target directory to the file
800 call WriteUninstallCtrlFile ("D " & InstallTarget)
802 ' Write the name of the file itself to the file
803 call WriteUninstallCtrlFile ("F " & UninstallCtrlFileName)
809 '******************************************************************************
810 ' Write to the uninstall control file
811 '******************************************************************************
812 sub WriteUninstallCtrlFile (Line)
815 UninstallCtrlFile.WriteLine (Line)
816 if Err.Number <> 0 then
818 Args(1) = UninstallCtrlFileName
819 Args(2) = Err.Description
820 call ErrorMsg (FmtMsg ("MSG_WRITEERR", Args))
828 '******************************************************************************
829 ' Close the uninstall control file
830 '******************************************************************************
831 sub CloseUninstallCtrlFile ()
834 UninstallCtrlFile.Close
835 if Err.Number <> 0 then
837 Args(1) = UninstallCtrlFileName
838 Args(2) = Err.Description
839 call ErrorMsg (FmtMsg ("MSG_WRITEERR", Args))
847 '******************************************************************************
848 ' Copy the application files
849 '******************************************************************************
850 sub RecursiveCopy (Dir, SourcePath, TargetPath)
852 dim File, TargetFile, SubDir, SourceName, TargetName, Result, Args(3)
854 ' Copy all files in this folder
855 for each File in Dir.Files
857 ' Generate source and target file names
858 SourceName = BuildPath (SourcePath, File.Name)
859 TargetName = BuildPath (TargetPath, File.Name)
861 ' Copy the file. The error check doesn't seem to work.
863 File.Copy (TargetName)
865 if Err.Number <> 0 then
868 Args(3) = Err.Description
869 call ErrorMsg (FmtMsg ("MSG_COPYERR", Args))
873 ' Remove the r/o attribute from the target file if set
874 set TargetFile = FSO.GetFile (TargetName)
875 if TargetFile.Attributes mod 2 = 1 then
876 TargetFile.Attributes = TargetFile.Attributes - 1
879 ' Remember this file in the uninstall control file
880 call WriteUninstallCtrlFile ("F " & TargetName)
883 ' Handle all subdirectories
884 for each SubDir in Dir.SubFolders
886 ' Update the progress bar with each copied directory
888 call ProgressBar (PBVal + 5)
891 ' Generate the new directory names
892 SourceName = BuildPath (SourcePath, SubDir.Name)
893 TargetName = BuildPath (TargetPath, SubDir.Name)
895 ' Generate the new target dir. Notify the user about errors, but
896 ' otherwise ignore them.
897 Result = CreateFolder (TargetName)
899 ' Display an error but try to continue
902 call ErrorMsg (FmtMsg ("MSG_CREATEERR", Args))
905 ' Recursively process files in the subdirectory
906 call RecursiveCopy (SubDir, SourceName, TargetName)
908 ' Remember the subdirectory in the uninstall control file
909 WriteUninstallCtrlFile ("D " & TargetName)
916 ' Update the progress bar
917 call ProgressBar (10)
919 ' Copy all files generating entries in the uninstall control file
920 call RecursiveCopy (FSO.GetFolder (InstallSource), InstallSource, InstallTarget)
922 ' Update the progress bar
923 call ProgressBar (90)
928 '******************************************************************************
929 ' Create the registry entries
930 '******************************************************************************
931 sub CreateRegEntries ()
935 ' Create the entry in Systemsteuerung -> Software. Check if the first write
936 ' succeeds. If not, we don't have admin rights.
937 if RegWriteBin (RegUninstall, 1) <> "" then
938 call Abort (GetMsg ("MSG_REGWRITEERR"))
940 call RegWriteStr (RegUninstall & "DisplayName", AppName & " " & Version)
941 call RegWriteStr (RegUninstall & "UninstallString", "wscript //nologo " & Uninstaller & " " & UninstallerCmdLine)
947 '******************************************************************************
948 ' Function that creates an URL
949 '******************************************************************************
950 sub CreateUrl (Name, Url, Description)
955 set Link = Shell.CreateShortcut (Name)
956 Link.TargetPath = Url
957 Link.Description = Description
963 ' Write the file name to the uninstall control file
964 WriteUninstallCtrlFile ("F " & Name)
969 '******************************************************************************
970 ' Function that creates a shortcut
971 '******************************************************************************
972 sub CreateShortcut (Name, Exe, Args, Description)
977 set Link = Shell.CreateShortcut (Name)
978 Link.TargetPath = Exe
979 Link.Arguments = Args
981 Link.Description = Description
982 Link.WorkingDirectory = AppData
988 ' Write the file name to the uninstall control file
989 WriteUninstallCtrlFile ("F " & Name)
994 '******************************************************************************
995 ' Function that creates the menu entries
996 '******************************************************************************
997 sub CreateMenuEntries ()
998 dim Folder, Result, Name, Desc, Target, Args(2)
1000 ' Create the start menu folder.
1001 Folder = BuildPath (Programs, AppName)
1002 Result = CreateFolder (Folder)
1003 if Result <> "" then
1004 ' Display an error but try to continue
1007 call ErrorMsg (FmtMsg ("MSG_CREATEERR", Args))
1010 ' Create an uninstall shortcut in the menu folder
1012 Desc = FmtMsg ("MSG_REMOVEENTRY", Args)
1013 Name = BuildPath (Folder, Desc & ".lnk")
1014 call CreateShortcut (Name, Uninstaller, UninstallerCmdLine, Desc)
1016 ' Create a documentation shortcut in the menu folder
1017 Target = BuildPath (InstallTarget, DocIndexFile)
1018 if FileExists (Target) then
1020 Desc = FmtMsg ("MSG_DOCENTRY", Args)
1021 Name = BuildPath (Folder, Desc & ".url")
1022 call CreateUrl (Name, "file://" & Target, Desc)
1025 ' Create the shortcut to the announcement in the menu folder
1026 Target = BuildPath (InstallTarget, AnnouncementFile)
1027 if FileExists (Target) then
1028 Desc = GetMsg ("MSG_ANNOUNCEMENT")
1029 Name = BuildPath (Folder, Desc & ".url")
1030 call CreateUrl (Name, "file://" & Target, Desc)
1033 ' Update the uninstall control file
1034 call WriteUninstallCtrlFile ("D " & Folder)
1039 '******************************************************************************
1040 ' Add a directory to the system path
1041 '******************************************************************************
1042 sub AddToSysPath (Dir)
1046 ' Handle errors. Assume failure
1047 on error resume next
1049 ' Retrieve the PATH setting
1050 Path = Shell.RegRead (SysPath)
1051 if Err.Number <> 0 then
1053 call Abort (GetMsg ("MSG_REGREADERR"))
1056 ' Add the new directory to the path
1057 if (Len (Path) > 0) and (Right (Path, 1) <> ";") then
1062 ' Write the new path
1063 call Shell.RegWrite (SysPath, Path, "REG_EXPAND_SZ")
1064 if Err.Number <> 0 then
1066 call Abort (GetMsg ("MSG_REGWRITEERR"))
1072 '******************************************************************************
1073 ' Add environment variables
1074 '******************************************************************************
1075 sub AddEnvironment ()
1078 if RegWriteStr (SysEnv & "\CC65_LIB", LibDir) <> "" then
1079 call Abort (GetMsg ("MSG_REGWRITEERR"))
1083 if RegWriteStr (SysEnv & "\CC65_INC", IncDir) <> "" then
1084 call Abort (GetMsg ("MSG_REGWRITEERR"))
1087 ' Add the bin directory to the path if it's not already there
1088 if not DirInPath (BinDir) then
1089 call AddToSysPath (BinDir)
1091 ' Run the wm_envchange program to notify other running programs
1092 ' of the changed environment. Ignore errors.
1093 call Run (BuildPath (BinDir, "wm_envchange.exe"), 0)
1100 '******************************************************************************
1101 ' Function that tells the user that the install was successful
1102 '******************************************************************************
1104 call MsgBox (GetMsg ("MSG_SUCCESS"), vbOkOnly + vbInformation, Installer)
1109 '******************************************************************************
1111 '******************************************************************************
1114 ' Initialize global variables. This includes the paths used
1115 call InitializeGlobals ()
1117 call ShowPathsAndLocations ()
1120 ' Check that there's something to install
1121 call CheckFilesToInstall ()
1123 ' Check that we're running this script as admin
1124 call CheckAdminRights ()
1126 ' Check if there is an old installation and offer to remove it
1127 call CheckOldInstall ()
1129 ' Check if the source directory does really exist
1130 call CheckInstallTarget ()
1132 ' Display the progress bar
1133 call ProgressBar (0)
1135 ' Create the uninstall file
1136 call CreateUninstallCtrlFile ()
1137 call ProgressBar (2)
1139 ' Create registry entries
1141 call Progressbar (5)
1143 ' Copy the application files (will do automatic progress bar updates)
1146 ' Create the menu entries
1147 call CreateMenuEntries ()
1148 call ProgressBar (90)
1150 ' Add entries to the enviroment
1151 call AddEnvironment ()
1152 call ProgressBar (95)
1154 ' Close the uninstall control file
1155 call CloseUninstallCtrlFile ()
1158 call ProgressBar (100)
1159 call ProgressBar (-1)
1162 ' Return a success code
1168 '******************************************************************************
1169 ' The script body just calls Main...
1170 '******************************************************************************