mirror of
https://github.com/cc65/cc65.git
synced 2025-01-14 00:32:08 +00:00
Simple windows installer/uninstaller
git-svn-id: svn://svn.cc65.org/cc65/trunk@3416 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
6b03c250c2
commit
9adac3c5b0
1148
packages/windows/install.vbs
Normal file
1148
packages/windows/install.vbs
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,120 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
set CC65VER=2.9.0
|
|
||||||
|
|
||||||
REM Cleanup old stuff
|
|
||||||
rm -r cc65
|
|
||||||
|
|
||||||
REM Create the directories
|
|
||||||
mkdir cc65 > nul
|
|
||||||
mkdir cc65\bin > nul
|
|
||||||
|
|
||||||
REM Copy stuff from trixie
|
|
||||||
for %i in (asminc doc emd include lib tgi) do (
|
|
||||||
if not exist u:\cc65\%i (
|
|
||||||
echo u:\cc65\%i does not exist
|
|
||||||
quit 1
|
|
||||||
)
|
|
||||||
mkdir cc65\%i
|
|
||||||
xcopy /q /s u:\cc65\%i\* cc65\%i
|
|
||||||
)
|
|
||||||
|
|
||||||
move /q cc65\doc\announce.txt cc65
|
|
||||||
ren /q cc65\doc\samples cc65\samples
|
|
||||||
|
|
||||||
REM Check if the compiler source exists
|
|
||||||
if not exist c:\uz\src\cc65 (
|
|
||||||
echo c:\uz\src\cc65 does not exist
|
|
||||||
quit 1
|
|
||||||
)
|
|
||||||
|
|
||||||
for %i in (apple2 atari c16 c64 c128 cbm510 cbm610 geos pet plus4 vic20) do (
|
|
||||||
setlocal
|
|
||||||
cd cc65
|
|
||||||
if exist u:\cc65\cc65-%i-%CC65VER%.zip del /q u:\cc65\cc65-%i-%CC65VER%.zip
|
|
||||||
zip -q9m u:\cc65\cc65-%i-%CC65VER%.zip lib\%i.lib lib\%i.o include\%i.h doc\%i.cfg
|
|
||||||
if exist emd\%i*.emd zip -q9m u:\cc65\cc65-%i-%CC65VER%.zip emd\%i*.emd
|
|
||||||
if exist tgi\%i*.tgi zip -q9m u:\cc65\cc65-%i-%CC65VER%.zip tgi\%i*.tgi
|
|
||||||
endlocal
|
|
||||||
)
|
|
||||||
|
|
||||||
REM Specials for the GEOS package
|
|
||||||
cd cc65
|
|
||||||
zip -q9mr u:\cc65\cc65-geos-%CC65VER%.zip include\geos samples\geos
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
REM Generate the win32 package
|
|
||||||
(
|
|
||||||
setlocal
|
|
||||||
cd src\cc65\src
|
|
||||||
gmake -f make\watcom.mak clean
|
|
||||||
gmake -f make\watcom.mak
|
|
||||||
gmake -f make\watcom.mak strip
|
|
||||||
endlocal
|
|
||||||
)
|
|
||||||
|
|
||||||
del /q /y cc65\bin\*
|
|
||||||
copy /q src\cc65\src\ar65\ar65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\ca65\ca65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\cc65\cc65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\cl65\cl65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\da65\da65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\grc\grc.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\ld65\ld65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\od65\od65.exe cc65\bin
|
|
||||||
if exist u:\cc65\cc65-win32-%CC65VER%.zip del /q u:\cc65\cc65-win32-%CC65VER%.zip
|
|
||||||
cd cc65
|
|
||||||
zip -q9r u:\cc65\cc65-win32-%CC65VER%.zip *
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
REM Generate the os2 package
|
|
||||||
(
|
|
||||||
setlocal
|
|
||||||
cd src\cc65\src
|
|
||||||
gmake -f make\watcom.mak clean
|
|
||||||
gmake -f make\watcom.mak os2
|
|
||||||
gmake -f make\watcom.mak strip
|
|
||||||
endlocal
|
|
||||||
)
|
|
||||||
|
|
||||||
del /q /y cc65\bin\*
|
|
||||||
copy /q src\cc65\src\ar65\ar65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\ca65\ca65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\cc65\cc65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\cl65\cl65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\da65\da65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\grc\grc.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\ld65\ld65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\od65\od65.exe cc65\bin
|
|
||||||
if exist u:\cc65\cc65-os2-%CC65VER%.zip del /q u:\cc65\cc65-os2-%CC65VER%.zip
|
|
||||||
cd cc65
|
|
||||||
zip -q9r u:\cc65\cc65-os2-%CC65VER%.zip *
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
REM Generate the dos32 package
|
|
||||||
(
|
|
||||||
setlocal
|
|
||||||
cd src\cc65\src
|
|
||||||
gmake -f make\watcom.mak clean
|
|
||||||
gmake -f make\watcom.mak dos
|
|
||||||
gmake -f make\watcom.mak strip
|
|
||||||
endlocal
|
|
||||||
)
|
|
||||||
|
|
||||||
del /q /y cc65\bin\*
|
|
||||||
copy /q src\cc65\src\ar65\ar65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\ca65\ca65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\cc65\cc65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\cl65\cl65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\da65\da65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\grc\grc.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\ld65\ld65.exe cc65\bin
|
|
||||||
copy /q src\cc65\src\od65\od65.exe cc65\bin
|
|
||||||
copy /q \watcom\binw\dos4gw.exe cc65\bin
|
|
||||||
if exist u:\cc65\cc65-dos32-%CC65VER%.zip del /q u:\cc65\cc65-dos32-%CC65VER%.zip
|
|
||||||
cd cc65
|
|
||||||
zip -q9r u:\cc65\cc65-dos32-%CC65VER%.zip *
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
|
|
||||||
|
|
679
packages/windows/uninstall.vbs
Normal file
679
packages/windows/uninstall.vbs
Normal file
@ -0,0 +1,679 @@
|
|||||||
|
Option Explicit ' Variables must be declared explicitly
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Global constants and variables
|
||||||
|
'******************************************************************************
|
||||||
|
dim Tab, NewLine ' String constants
|
||||||
|
dim Shell, FSO ' Global objects
|
||||||
|
dim ProgArgs ' Program arguments
|
||||||
|
dim Dbg ' Output debugging stuff
|
||||||
|
dim Language ' Program language
|
||||||
|
dim AppName ' Application name
|
||||||
|
dim Title ' Application title
|
||||||
|
dim UninstallCtrlFileName ' Name of the uninstall control file
|
||||||
|
dim SystemDrive ' The system drive
|
||||||
|
dim SystemRoot ' The windows directory
|
||||||
|
dim UserName ' Name if the current user
|
||||||
|
dim UserProfile ' User profile directory
|
||||||
|
dim ProgramFiles ' Program files directory
|
||||||
|
dim Failed ' Global flag for removal failed
|
||||||
|
dim RegList ' List of registry entries to remove
|
||||||
|
dim FileList ' List of files to remove
|
||||||
|
dim DirList ' List of directories to remove
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Display an error message window with an OK button
|
||||||
|
'******************************************************************************
|
||||||
|
sub ErrorMsg (Msg)
|
||||||
|
call MsgBox (Msg, vbOkOnly + vbExclamation, Title)
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Display an error message window and abort the installer
|
||||||
|
'******************************************************************************
|
||||||
|
sub Abort (Msg)
|
||||||
|
call ErrorMsg (Msg)
|
||||||
|
WScript.Quit (1)
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Convert a number to a string
|
||||||
|
'******************************************************************************
|
||||||
|
function ToString (Num)
|
||||||
|
ToString = FormatNumber (Num, vbFalse, vbTrue, vbFalse, vbFalse)
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Return a message in the current language
|
||||||
|
'******************************************************************************
|
||||||
|
function GetMsg (Key)
|
||||||
|
dim Msg
|
||||||
|
|
||||||
|
' Handle other languages here
|
||||||
|
|
||||||
|
' Default is english
|
||||||
|
if IsEmpty (Msg) then
|
||||||
|
' No assignment, use english
|
||||||
|
select case Key
|
||||||
|
case "MSG_ABORT"
|
||||||
|
Msg = "Do you want to abort the installation?"
|
||||||
|
case "MSG_ADMIN"
|
||||||
|
Msg = "You must be Administrator to remove %1."
|
||||||
|
Msg = Msg & " Are you sure you want to continue?"
|
||||||
|
case "MSG_CTRLFILEERR"
|
||||||
|
Msg = "The file %1 is invalid." & NewLine
|
||||||
|
Msg = Msg & "Line %2: %3"
|
||||||
|
case "MSG_DIRDEL"
|
||||||
|
Msg = "Some folders could not be removed:"
|
||||||
|
Msg = Msg & NewLine & "%1"
|
||||||
|
case "MSG_DUPLICATE"
|
||||||
|
Msg = "Duplicate value"
|
||||||
|
case "MSG_FAILURE"
|
||||||
|
Msg = "Could not remove %1." & NewLine
|
||||||
|
Msg = "%2 needs to be run by an Administrator!"
|
||||||
|
case "MSG_FILEDEL"
|
||||||
|
Msg = "Some files could not be deleted:"
|
||||||
|
Msg = Msg & NewLine & "%1"
|
||||||
|
case "MSG_OPENERR"
|
||||||
|
Msg = "Error opening %1"
|
||||||
|
case "MSG_REGDEL"
|
||||||
|
Msg = "Some registry entries could not be deleted:"
|
||||||
|
Msg = Msg & NewLine & "%1"
|
||||||
|
case "MSG_REMOVE"
|
||||||
|
Msg = "Remove %1?"
|
||||||
|
case "MSG_SUCCESS"
|
||||||
|
Msg = "%1 has been successfully removed."
|
||||||
|
case "MSG_USAGE"
|
||||||
|
Msg = "Usage:" & NewLine & "uninstall appname ctrl-file"
|
||||||
|
case else
|
||||||
|
Msg = Key
|
||||||
|
end select
|
||||||
|
end if
|
||||||
|
GetMsg = Msg
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Format a string replacing %n specifiers in the format string F
|
||||||
|
'******************************************************************************
|
||||||
|
function Fmt (F, Values)
|
||||||
|
dim I, Count, Key, Val, Start, Pos
|
||||||
|
Count = UBound (Values) ' How many values?
|
||||||
|
for I = Count to 0 step -1
|
||||||
|
Key = "%" & ToString (I)
|
||||||
|
select case VarType (Values (I))
|
||||||
|
case vbEmpty
|
||||||
|
Val = ""
|
||||||
|
case vbInteger
|
||||||
|
Val = ToString (Values (I))
|
||||||
|
case vbLong
|
||||||
|
Val = ToString (Values (I))
|
||||||
|
case vbNull
|
||||||
|
Val = ""
|
||||||
|
case vbSingle
|
||||||
|
Val = ToString (Values (I))
|
||||||
|
case vbDouble
|
||||||
|
Val = ToString (Values (I))
|
||||||
|
case vbString
|
||||||
|
Val = Values (I)
|
||||||
|
case else
|
||||||
|
Abort ("Internal error: Invalid conversion in Format()")
|
||||||
|
end select
|
||||||
|
F = Replace (F, Key, Val)
|
||||||
|
next
|
||||||
|
Fmt = F
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Format a message replacing %n specifiers in the format string F
|
||||||
|
'******************************************************************************
|
||||||
|
function FmtMsg (Msg, Values)
|
||||||
|
FmtMsg = Fmt (GetMsg (Msg), Values)
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Return an environment string. Fix up Microsoft "innovative" ideas.
|
||||||
|
'******************************************************************************
|
||||||
|
function GetEnv (Key)
|
||||||
|
dim Value
|
||||||
|
Value = Shell.ExpandEnvironmentStrings (Key)
|
||||||
|
if Value = Key then
|
||||||
|
GetEnv = vbNullString
|
||||||
|
else
|
||||||
|
GetEnv = Value
|
||||||
|
end if
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Build a path from two components
|
||||||
|
'******************************************************************************
|
||||||
|
function BuildPath (Path, Name)
|
||||||
|
BuildPath = FSO.BuildPath (Path, Name)
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Delete a folder and return an error string
|
||||||
|
'******************************************************************************
|
||||||
|
function DeleteFolder (Path)
|
||||||
|
on error resume next
|
||||||
|
call FSO.DeleteFolder (Path, true)
|
||||||
|
DeleteFolder = Err.Description
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Delete a file and return an error string
|
||||||
|
'******************************************************************************
|
||||||
|
function DeleteFile (Path)
|
||||||
|
on error resume next
|
||||||
|
call FSO.DeleteFile (Path, true)
|
||||||
|
DeleteFile = Err.Description
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Delete a registry entry
|
||||||
|
'******************************************************************************
|
||||||
|
function RegDelete (Key)
|
||||||
|
on error resume next
|
||||||
|
call Shell.RegDelete (Key)
|
||||||
|
RegDelete = Err.Description
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Sort an array of strings
|
||||||
|
'******************************************************************************
|
||||||
|
sub QS (byref A, Lo, Hi)
|
||||||
|
|
||||||
|
dim I, J, T
|
||||||
|
|
||||||
|
' Quicksort
|
||||||
|
do while Hi > Lo
|
||||||
|
I = Lo + 1
|
||||||
|
J = Hi
|
||||||
|
do while I <= J
|
||||||
|
do while I <= J
|
||||||
|
if StrComp (A(Lo), A(I), vbTextCompare) < 0 then
|
||||||
|
exit do
|
||||||
|
end if
|
||||||
|
I = I + 1
|
||||||
|
loop
|
||||||
|
do while I <= J
|
||||||
|
if StrComp (A(Lo), A(J), vbTextCompare) >= 0 then
|
||||||
|
exit do
|
||||||
|
end if
|
||||||
|
J = J - 1
|
||||||
|
loop
|
||||||
|
if I <= J then
|
||||||
|
' Swap A(I) and A(J)
|
||||||
|
T = A(I)
|
||||||
|
A(I) = A(J)
|
||||||
|
A(J) = T
|
||||||
|
I = I + 1
|
||||||
|
J = J - 1
|
||||||
|
end if
|
||||||
|
loop
|
||||||
|
if J <> Lo then
|
||||||
|
' Swap A(J) and A(Lo)
|
||||||
|
T = A(J)
|
||||||
|
A(J) = A(Lo)
|
||||||
|
A(Lo) = T
|
||||||
|
end if
|
||||||
|
if (2 * J) > (Hi + Lo) then
|
||||||
|
call QS (A, J + 1, Hi)
|
||||||
|
Hi = J - 1
|
||||||
|
else
|
||||||
|
call QS (A, Lo, J - 1)
|
||||||
|
Lo = J + 1
|
||||||
|
end if
|
||||||
|
loop
|
||||||
|
end sub
|
||||||
|
|
||||||
|
sub Quicksort (byref A)
|
||||||
|
if UBound (A) > 1 then
|
||||||
|
call QS (A, LBound (A), UBound (A))
|
||||||
|
end if
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Initialize global variables
|
||||||
|
'******************************************************************************
|
||||||
|
sub InitializeGlobals ()
|
||||||
|
dim I
|
||||||
|
|
||||||
|
' String stuff used for formatting
|
||||||
|
Tab = Chr (9)
|
||||||
|
NewLine = Chr (13)
|
||||||
|
|
||||||
|
' Global objects
|
||||||
|
set Shell = WScript.CreateObject ("WScript.Shell")
|
||||||
|
set FSO = CreateObject ("Scripting.FileSystemObject")
|
||||||
|
|
||||||
|
' Arguments
|
||||||
|
set ProgArgs = WScript.Arguments
|
||||||
|
|
||||||
|
' Handle program arguments
|
||||||
|
AppName = ""
|
||||||
|
Title = "Uninstaller"
|
||||||
|
UninstallCtrlFileName = ""
|
||||||
|
Dbg = false
|
||||||
|
Language = "de"
|
||||||
|
for I = 0 to ProgArgs.Count-1
|
||||||
|
select case ProgArgs(I)
|
||||||
|
case "-de"
|
||||||
|
Language = "de"
|
||||||
|
case "-debug"
|
||||||
|
Dbg = true
|
||||||
|
case "-en"
|
||||||
|
Language = "en"
|
||||||
|
case else
|
||||||
|
if AppName = "" then
|
||||||
|
AppName = ProgArgs(I)
|
||||||
|
elseif UninstallCtrlFileName = "" then
|
||||||
|
UninstallCtrlFileName = ProgArgs(I)
|
||||||
|
else
|
||||||
|
call ErrorMsg (GetMsg ("MSG_USAGE"))
|
||||||
|
WScript.Quit (1)
|
||||||
|
end if
|
||||||
|
end select
|
||||||
|
next
|
||||||
|
|
||||||
|
' We need the application name and uninstall control file
|
||||||
|
if AppName = "" or UninstallCtrlFileName = "" then
|
||||||
|
call Abort (GetMsg ("MSG_USAGE"))
|
||||||
|
end if
|
||||||
|
|
||||||
|
' Set the title early, because it's used in error messages
|
||||||
|
Title = AppName & " Uninstaller"
|
||||||
|
|
||||||
|
' Paths and locations
|
||||||
|
SystemDrive = GetEnv ("%SystemDrive%")
|
||||||
|
if SystemDrive = vbNullString then
|
||||||
|
SystemDrive = "c:"
|
||||||
|
end if
|
||||||
|
SystemRoot = GetEnv ("%SystemRoot%")
|
||||||
|
if SystemRoot = vbNullString then
|
||||||
|
SystemRoot = BuildPath (SystemDrive, "winnt")
|
||||||
|
end if
|
||||||
|
UserName = GetEnv ("%USERNAME%")
|
||||||
|
if UserName = vbNullString then
|
||||||
|
UserName = "Administrator"
|
||||||
|
end if
|
||||||
|
UserProfile = GetEnv ("%USERPROFILE%")
|
||||||
|
if UserProfile = vbNullString then
|
||||||
|
UserProfile = BuildPath (SystemDrive, "Dokumente und Einstellungen\" & UserName)
|
||||||
|
end if
|
||||||
|
ProgramFiles = GetEnv ("%ProgramFiles%")
|
||||||
|
if ProgramFiles = vbNullString then
|
||||||
|
ProgramFiles = BuildPath (SystemDrive, "Programme")
|
||||||
|
end if
|
||||||
|
|
||||||
|
' Assume we could remove the software
|
||||||
|
Failed = false
|
||||||
|
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Ask a yes/no question and return the result. "Yes" is default.
|
||||||
|
'******************************************************************************
|
||||||
|
function AskYesNo (Question)
|
||||||
|
AskYesNo = MsgBox (Question, vbYesNo + vbQuestion + vbDefaultButton1, Title)
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Ask a yes/no question and return the result. "No" is default.
|
||||||
|
'******************************************************************************
|
||||||
|
function AskNoYes (Question)
|
||||||
|
AskNoYes = MsgBox (Question, vbYesNo + vbQuestion + vbDefaultButton2, Title)
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Ask if the user wants to abort install, and terminate if the answer is yes
|
||||||
|
'******************************************************************************
|
||||||
|
sub QueryAbort ()
|
||||||
|
if AskNoYes (GetMsg ("MSG_ABORT")) = vbYes then
|
||||||
|
WScript.Quit (1)
|
||||||
|
end if
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Function that displays the paths and locations found
|
||||||
|
'******************************************************************************
|
||||||
|
function OneLoc (Key, Value)
|
||||||
|
dim Result
|
||||||
|
Result = Trim (Key)
|
||||||
|
if Len (Result) <= 8 then
|
||||||
|
Result = Result & Tab
|
||||||
|
end if
|
||||||
|
OneLoc = Result & Tab & "=" & Tab & Value & NewLine
|
||||||
|
end function
|
||||||
|
|
||||||
|
sub ShowPathsAndLocations ()
|
||||||
|
dim Msg
|
||||||
|
Msg = Msg & OneLoc ("SystemDrive", SystemDrive)
|
||||||
|
Msg = Msg & OneLoc ("SystemRoot", SystemRoot)
|
||||||
|
Msg = Msg & OneLoc ("UserName", UserName)
|
||||||
|
Msg = Msg & OneLoc ("UserProfile", UserProfile)
|
||||||
|
Msg = Msg & OneLoc ("ProgramFiles", ProgramFiles)
|
||||||
|
|
||||||
|
MsgBox Msg, vbOkOnly, "Paths and Locations"
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Check that were running this script as admin
|
||||||
|
'******************************************************************************
|
||||||
|
sub CheckAdminRights ()
|
||||||
|
|
||||||
|
' FIXME: This check is not perfect
|
||||||
|
if UserName <> "Administrator" then
|
||||||
|
dim Args(1)
|
||||||
|
Args(1) = AppName
|
||||||
|
|
||||||
|
if AskNoYes (FmtMsg ("MSG_ADMIN", Args)) <> vbYes then
|
||||||
|
WScript.Quit (1)
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Read the uninstall control file and create the data collections
|
||||||
|
'******************************************************************************
|
||||||
|
sub InvalidCtrlFile (Line, Val)
|
||||||
|
dim Args(3)
|
||||||
|
Args(1) = UninstallCtrlFileName
|
||||||
|
Args(2) = Line
|
||||||
|
Args(3) = Val
|
||||||
|
call Abort (FmtMsg ("MSG_CTRLFILEERR", Args))
|
||||||
|
end sub
|
||||||
|
|
||||||
|
sub ReadUninstallCtrlFile ()
|
||||||
|
|
||||||
|
const ForReading = 1
|
||||||
|
dim File, Line, Tag, Args(3)
|
||||||
|
dim MyRegList, MyFileList, myDirList
|
||||||
|
|
||||||
|
' Create some dictionaries. These are not really used as dictionaries, but
|
||||||
|
' have the nice property of expanding dynamically, and we need that.
|
||||||
|
set MyRegList = CreateObject ("Scripting.Dictionary")
|
||||||
|
set MyFileList = CreateObject ("Scripting.Dictionary")
|
||||||
|
set MyDirList = CreateObject ("Scripting.Dictionary")
|
||||||
|
|
||||||
|
' Open the file. Checking Err doesn't work here, don't know why.
|
||||||
|
set File = nothing
|
||||||
|
on error resume next
|
||||||
|
set File = FSO.OpenTextFile (UninstallCtrlFileName, ForReading)
|
||||||
|
on error goto 0
|
||||||
|
if File is nothing then
|
||||||
|
Args(1) = UninstallCtrlFileName
|
||||||
|
call Abort (FmtMsg ("MSG_OPENERR", Args))
|
||||||
|
end if
|
||||||
|
|
||||||
|
' Read all lines and insert them in their list
|
||||||
|
do while File.AtEndOfStream <> true
|
||||||
|
|
||||||
|
' Read the next line
|
||||||
|
on error resume next
|
||||||
|
Line = File.ReadLine
|
||||||
|
on error goto 0
|
||||||
|
|
||||||
|
' Get the type from the line and remove it, so the line contains just
|
||||||
|
' the argument name
|
||||||
|
Tag = Left (Line, 1)
|
||||||
|
Line = Mid (Line, 3)
|
||||||
|
|
||||||
|
' Determine the type of the entry
|
||||||
|
select case Tag
|
||||||
|
|
||||||
|
case "D"
|
||||||
|
' A directory. Convert to lowercase to unify names.
|
||||||
|
Line = LCase (Line)
|
||||||
|
if MyDirList.Exists (Line) then
|
||||||
|
call InvalidCtrlFile (File.Line - 1, GetMsg ("MSG_DUPLICATE"))
|
||||||
|
else
|
||||||
|
call MyDirList.Add (Line, "")
|
||||||
|
end if
|
||||||
|
|
||||||
|
case "F"
|
||||||
|
' A file. Convert to lowercase to unify names
|
||||||
|
Line = LCase (Line)
|
||||||
|
if MyFileList.Exists (Line) then
|
||||||
|
call InvalidCtrlFile (File.Line - 1, GetMsg ("MSG_DUPLICATE"))
|
||||||
|
else
|
||||||
|
call MyFileList.Add (Line, "")
|
||||||
|
end if
|
||||||
|
|
||||||
|
case "R"
|
||||||
|
' A registry entry
|
||||||
|
if MyRegList.Exists (Line) then
|
||||||
|
call InvalidCtrlFile (File.Line - 1, GetMsg ("MSG_DUPLICATE"))
|
||||||
|
else
|
||||||
|
call MyRegList.Add (Line, "")
|
||||||
|
end if
|
||||||
|
|
||||||
|
case else
|
||||||
|
call InvalidCtrlFile (File.Line - 1, Tag & " " & Line)
|
||||||
|
|
||||||
|
end select
|
||||||
|
|
||||||
|
loop
|
||||||
|
|
||||||
|
' Close the file
|
||||||
|
on error resume next
|
||||||
|
call File.Close ()
|
||||||
|
on error goto 0
|
||||||
|
|
||||||
|
' Make the global arrays big enough for the data
|
||||||
|
RegList = Array (MyRegList.Count)
|
||||||
|
FileList = Array (MyFileList.Count)
|
||||||
|
DirList = Array (MyDirList.Count)
|
||||||
|
|
||||||
|
' Copy the data into the global arrays
|
||||||
|
RegList = MyRegList.Keys
|
||||||
|
FileList = MyFileList.Keys
|
||||||
|
DirList = MyDirList.Keys
|
||||||
|
|
||||||
|
' Sort all the lists. This makes sure nodes are in the array before the
|
||||||
|
' leaves that depend on it. Or in other words: Top level directories and
|
||||||
|
' registry entries come first. So if we delete the items starting at the
|
||||||
|
' other side of the array, we will never delete a subdirectory before its
|
||||||
|
' parent directory.
|
||||||
|
call QuickSort (RegList)
|
||||||
|
call QuickSort (FileList)
|
||||||
|
call QuickSort (DirList)
|
||||||
|
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Delete the registry entries
|
||||||
|
'******************************************************************************
|
||||||
|
sub DeleteRegistryEntries ()
|
||||||
|
|
||||||
|
dim I, Result, NoDel, Args(1)
|
||||||
|
|
||||||
|
NoDel = ""
|
||||||
|
for I = UBound (RegList) to LBound (RegList) step -1
|
||||||
|
Result = RegDelete (RegList (I))
|
||||||
|
if Result <> "" then
|
||||||
|
' Remember the entries we could not delete
|
||||||
|
NoDel = NoDel & RegList (I) & NewLine
|
||||||
|
end if
|
||||||
|
next
|
||||||
|
|
||||||
|
if NoDel <> "" then
|
||||||
|
Args(1) = NoDel
|
||||||
|
call ErrorMsg (FmtMsg ("MSG_REGDEL", Args))
|
||||||
|
end if
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Delete the files
|
||||||
|
'******************************************************************************
|
||||||
|
sub DeleteFiles ()
|
||||||
|
|
||||||
|
dim I, Result, NoDel, Args(1)
|
||||||
|
|
||||||
|
NoDel = ""
|
||||||
|
for I = UBound (FileList) to LBound (FileList) step -1
|
||||||
|
Result = DeleteFile (FileList (I))
|
||||||
|
if Result <> "" then
|
||||||
|
' Remember the files we could not delete
|
||||||
|
NoDel = NoDel & FileList (I) & NewLine
|
||||||
|
end if
|
||||||
|
next
|
||||||
|
|
||||||
|
if NoDel <> "" then
|
||||||
|
Args(1) = NoDel
|
||||||
|
call ErrorMsg (FmtMsg ("MSG_FILEDEL", Args))
|
||||||
|
end if
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Delete the directories
|
||||||
|
'******************************************************************************
|
||||||
|
sub DeleteDirectories ()
|
||||||
|
|
||||||
|
dim I, Result, NoDel, Args(1)
|
||||||
|
|
||||||
|
NoDel = ""
|
||||||
|
for I = UBound (DirList) to LBound (DirList) step -1
|
||||||
|
Result = DeleteFolder (DirList (I))
|
||||||
|
if Result <> "" then
|
||||||
|
' Remember the directories we could not delete
|
||||||
|
NoDel = NoDel & DirList (I) & NewLine
|
||||||
|
end if
|
||||||
|
next
|
||||||
|
|
||||||
|
if NoDel <> "" then
|
||||||
|
Args(1) = NoDel
|
||||||
|
call ErrorMsg (FmtMsg ("MSG_DIRDEL", Args))
|
||||||
|
end if
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Function that tells the user that the install was successful
|
||||||
|
'******************************************************************************
|
||||||
|
sub Success ()
|
||||||
|
dim Args(1), App
|
||||||
|
|
||||||
|
' Popup message
|
||||||
|
Args(1) = AppName
|
||||||
|
call MsgBox (FmtMsg ("MSG_SUCCESS", Args), vbOkOnly + vbInformation, Title)
|
||||||
|
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Function that tells the user that the uninstall failed
|
||||||
|
'******************************************************************************
|
||||||
|
sub Failure ()
|
||||||
|
dim Args(2)
|
||||||
|
|
||||||
|
' Popup message
|
||||||
|
Args(1) = AppName
|
||||||
|
Args(2) = Title
|
||||||
|
ErrorMsg (FmtMsg ("MSG_FAILURE", Args))
|
||||||
|
WScript.Quit (1)
|
||||||
|
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Main program
|
||||||
|
'******************************************************************************
|
||||||
|
sub Main ()
|
||||||
|
|
||||||
|
dim Args(1)
|
||||||
|
|
||||||
|
' Initialize global variables. This includes the paths used
|
||||||
|
InitializeGlobals ()
|
||||||
|
if Dbg then
|
||||||
|
ShowPathsAndLocations ()
|
||||||
|
end if
|
||||||
|
|
||||||
|
' Check that we're running this script as admin
|
||||||
|
CheckAdminRights ()
|
||||||
|
|
||||||
|
' Let the user make up his mind
|
||||||
|
Args(1) = AppName
|
||||||
|
if AskYesNo (FmtMsg ("MSG_REMOVE", Args)) <> vbYes then
|
||||||
|
WScript.Quit (1)
|
||||||
|
end if
|
||||||
|
|
||||||
|
' Read the uninstall control file
|
||||||
|
call ReadUninstallCtrlFile ()
|
||||||
|
|
||||||
|
' Delete the registry entries
|
||||||
|
call DeleteRegistryEntries ()
|
||||||
|
|
||||||
|
' Delete all files
|
||||||
|
call DeleteFiles ()
|
||||||
|
|
||||||
|
' Delete the directories
|
||||||
|
call DeleteDirectories ()
|
||||||
|
|
||||||
|
' We're done
|
||||||
|
if Failed then
|
||||||
|
Failure ()
|
||||||
|
else
|
||||||
|
Success ()
|
||||||
|
end if
|
||||||
|
end sub
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' The script body just calls Main...
|
||||||
|
'******************************************************************************
|
||||||
|
Main ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
14
packages/windows/wm_envchange.c
Normal file
14
packages/windows/wm_envchange.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
/* Broadcast the WM_SETTINGCHANGE message with the lParam argument set
|
||||||
|
* to a pointer to the string "Environment" (one of the many undocumented
|
||||||
|
* Microsoft kludges).
|
||||||
|
*/
|
||||||
|
SendMessage (HWND_BROADCAST, WM_SETTINGCHANGE, NULL, (LONG) "Environment");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user