Merge branch 'master' of https://github.com/overdodactyl/ShadowFox
This commit is contained in:
commit
f9376b8971
|
@ -2,21 +2,25 @@ option explicit
|
||||||
|
|
||||||
' ShadowFox updater for Windows
|
' ShadowFox updater for Windows
|
||||||
' author: @CarlColijn
|
' author: @CarlColijn
|
||||||
' version: 1.0
|
' version: 1.1
|
||||||
|
' ^^^ ensure the version number is a numeric float value!
|
||||||
|
|
||||||
' the download urls of the files
|
' the download urls of the files
|
||||||
const chromeFileURL = "https://raw.githubusercontent.com/overdodactyl/ShadowFox/master/userChrome.css"
|
const chromeFileURL = "https://raw.githubusercontent.com/overdodactyl/ShadowFox/master/userChrome.css"
|
||||||
const contentFileURL = "https://raw.githubusercontent.com/overdodactyl/ShadowFox/master/userContent.css"
|
const contentFileURL = "https://raw.githubusercontent.com/overdodactyl/ShadowFox/master/userContent.css"
|
||||||
|
const updaterFileURL = "https://raw.githubusercontent.com/overdodactyl/ShadowFox/master/scripts/ShadowFox_updater_windows.vbs"
|
||||||
|
|
||||||
' set up the common worker objects and flags
|
' set up the common worker objects and flags
|
||||||
dim vbSection: vbSection = vbNewLine & vbNewLine
|
dim vbSection: vbSection = vbNewLine & vbNewLine
|
||||||
const readMode = 1
|
const forReading = 1
|
||||||
const binaryMode = 1
|
const adTypeBinary = 1
|
||||||
const overwriteMode = 2
|
const adTypeText = 2
|
||||||
|
const adSaveCreateOverWrite = 2
|
||||||
dim fso: set fso = createObject("Scripting.FileSystemObject")
|
dim fso: set fso = createObject("Scripting.FileSystemObject")
|
||||||
dim regEx: set regEx = createObject("VBScript.RegExp")
|
dim regEx: set regEx = createObject("VBScript.RegExp")
|
||||||
regEx.global = true
|
regEx.global = true
|
||||||
regEx.ignoreCase = true
|
regEx.ignoreCase = true
|
||||||
|
dim shell: set shell = createObject("WScript.Shell")
|
||||||
|
|
||||||
' vb's IIf replacement
|
' vb's IIf replacement
|
||||||
function iif(condition, trueValue, falseValue)
|
function iif(condition, trueValue, falseValue)
|
||||||
|
@ -57,33 +61,58 @@ function dateTimeStamp()
|
||||||
end function
|
end function
|
||||||
|
|
||||||
' backs up the given file
|
' backs up the given file
|
||||||
|
' creates the backup folder if it doesn't exist yet
|
||||||
' returns the used backup file name
|
' returns the used backup file name
|
||||||
function backupFile(chromeFolderPath, filePath, fileBaseName)
|
function backupFile(sourceFilePath, backupFolderPath)
|
||||||
|
' determine the backup filename
|
||||||
|
dim backupFileName: backupFileName = fso.getBaseName(sourceFilePath) & ".backup." & dateTimeStamp() & "." & fso.getExtensionName(sourceFilePath)
|
||||||
|
dim backupFilePath: backupFilePath = fso.buildPath(backupFolderPath, backupFileName)
|
||||||
|
|
||||||
|
' ensure the backup folder is there
|
||||||
|
if not fso.folderExists(backupFolderPath) then
|
||||||
|
call fso.createFolder(backupFolderPath)
|
||||||
|
end if
|
||||||
|
|
||||||
' backup the file
|
' backup the file
|
||||||
dim backupFileName: backupFileName = fileBaseName & ".backup." & dateTimeStamp() & ".css"
|
call fso.moveFile(sourceFilePath, backupFilePath)
|
||||||
dim backupFilePath: backupFilePath = fso.buildPath(chromeFolderPath, backupFileName)
|
|
||||||
call fso.moveFile(filePath, backupFilePath)
|
|
||||||
|
|
||||||
' and tell where the backup ended up
|
' and tell where the backup ended up
|
||||||
backupFile = backupFileName
|
backupFile = backupFileName
|
||||||
end function
|
end function
|
||||||
|
|
||||||
' downloads the given file to the given location
|
' reads the given file's content
|
||||||
' returns if the download succeeded
|
function readFileContent(filePath)
|
||||||
function downloadFile(url, filePath)
|
if fso.getFile(filePath).size = 0 then
|
||||||
|
readFileContent = ""
|
||||||
|
else
|
||||||
|
readFileContent = fso.openTextFile(filePath, forReading).readAll()
|
||||||
|
end if
|
||||||
|
end function
|
||||||
|
|
||||||
|
' writes the given file's content
|
||||||
|
function writeFileContent(filePath, content)
|
||||||
|
call fso.createTextFile(filePath, true).write(content)
|
||||||
|
end function
|
||||||
|
|
||||||
|
' downloads the given file
|
||||||
|
' returns the content and if the download succeeded
|
||||||
|
function downloadFile(url, content)
|
||||||
on error resume next
|
on error resume next
|
||||||
' download the file content
|
' download the file content
|
||||||
dim xmlHttp: set xmlHttp = createObject("Microsoft.XMLHTTP")
|
dim xmlHttp: set xmlHttp = createObject("Microsoft.XMLHTTP")
|
||||||
call xmlHttp.Open("GET", url, false)
|
call xmlHttp.Open("GET", url, false)
|
||||||
call xmlHttp.Send()
|
call xmlHttp.Send()
|
||||||
if err.number = 0 then
|
if err.number = 0 then
|
||||||
' done -> save it
|
' done -> convert it
|
||||||
dim stream: set stream = createobject("ADODB.Stream")
|
dim stream: set stream = createobject("ADODB.Stream")
|
||||||
with stream
|
with stream
|
||||||
.type = binaryMode
|
.type = adTypeBinary
|
||||||
call .open
|
call .open
|
||||||
call .write(xmlHttp.responseBody)
|
call .write(xmlHttp.responseBody)
|
||||||
call .saveToFile(filePath, overwriteMode)
|
.position = 0
|
||||||
|
.type = adTypeText
|
||||||
|
.charSet = "us-ascii"
|
||||||
|
content = .readText()
|
||||||
end with
|
end with
|
||||||
end if
|
end if
|
||||||
|
|
||||||
|
@ -92,12 +121,15 @@ function downloadFile(url, filePath)
|
||||||
on error goto 0
|
on error goto 0
|
||||||
end function
|
end function
|
||||||
|
|
||||||
' reads the given file's content
|
' downloads and saves the given file to the given location
|
||||||
function readFileContent(filePath)
|
' returns if the download succeeded
|
||||||
if fso.getFile(filePath).size = 0 then
|
function downloadAndSaveFile(url, filePath)
|
||||||
readFileContent = ""
|
' download the file's content
|
||||||
else
|
dim content
|
||||||
readFileContent = fso.openTextFile(filePath, readMode).readAll()
|
downloadAndSaveFile = downloadFile(url, content)
|
||||||
|
if downloadAndSaveFile then
|
||||||
|
' done -> save it's content
|
||||||
|
call writeFileContent(filePath, content)
|
||||||
end if
|
end if
|
||||||
end function
|
end function
|
||||||
|
|
||||||
|
@ -117,10 +149,165 @@ function processCustomizationFile(filePath)
|
||||||
end if
|
end if
|
||||||
end function
|
end function
|
||||||
|
|
||||||
|
' reads in the given ini file
|
||||||
|
' returns a dict of dicts, where the outer dict keys on the sections and the inner dicts on the keys
|
||||||
|
function readIni(iniFilePath)
|
||||||
|
' get the ini's content
|
||||||
|
dim iniLines: iniLines = split(normalizeLineEndings(readFileContent(iniFilePath)), vbLf)
|
||||||
|
|
||||||
|
' and parse it
|
||||||
|
set readIni = CreateObject("Scripting.Dictionary")
|
||||||
|
dim currentSection: set currentSection = Nothing
|
||||||
|
dim nextLine
|
||||||
|
for each nextLine in iniLines
|
||||||
|
' get the next line
|
||||||
|
nextLine = trim(nextLine)
|
||||||
|
if len(nextLine) > 0 then
|
||||||
|
' done -> look what we have
|
||||||
|
if left(nextLine, 1) = "[" then
|
||||||
|
' a section -> switch to it
|
||||||
|
dim nextSectionName: nextSectionName = mid(nextLine, 2, len(nextLine) - 2)
|
||||||
|
if readIni.exists(nextSectionName) then
|
||||||
|
set currentSection = readIni.item(nextSectionName)
|
||||||
|
else
|
||||||
|
set currentSection = CreateObject("Scripting.Dictionary")
|
||||||
|
set readIni.item(nextSectionName) = currentSection
|
||||||
|
end if
|
||||||
|
else
|
||||||
|
' a key -> add it
|
||||||
|
dim endKeyPos: endKeyPos = inStr(nextLine, "=")
|
||||||
|
if endKeyPos >= 1 and not currentSection is nothing then
|
||||||
|
dim nextKey: nextKey = trim(left(nextLine, endKeyPos - 1))
|
||||||
|
dim nextValue: nextValue = mid(nextLine, endKeyPos + 1)
|
||||||
|
currentSection.item(nextKey) = nextValue
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
next
|
||||||
|
end function
|
||||||
|
|
||||||
|
' gets the path to the profile folder to update
|
||||||
|
' returns "" if more than one profile exists but the user cancels
|
||||||
|
function getProfileFolderPath()
|
||||||
|
' determine where the FireFox files are located
|
||||||
|
dim userDataFolderPath: userDataFolderPath = shell.ExpandEnvironmentStrings("%APPDATA%\Mozilla\FireFox")
|
||||||
|
dim profileIniFilePath: profileIniFilePath = fso.buildPath(userDataFolderPath, "profiles.ini")
|
||||||
|
|
||||||
|
' determine where we are located
|
||||||
|
dim ourPath: ourPath = fso.getParentFolderName(wscript.scriptFullName)
|
||||||
|
|
||||||
|
' get the profiles configuration
|
||||||
|
dim iniContent: set iniContent = readIni(profileIniFilePath)
|
||||||
|
|
||||||
|
' extract the names & paths of the profiles found
|
||||||
|
dim profilePaths: set profilePaths = CreateObject("Scripting.Dictionary")
|
||||||
|
profilePaths.compareMode = VBTextCompare
|
||||||
|
dim sectionName
|
||||||
|
dim defaultProfileName: defaultProfileName = ""
|
||||||
|
dim forcedProfilePath: forcedProfilePath = ""
|
||||||
|
for each sectionName in iniContent.keys()
|
||||||
|
if lcase(left(sectionName, 7)) = "profile" then
|
||||||
|
dim section: set section = iniContent.item(sectionName)
|
||||||
|
dim name: name = section.item("Name")
|
||||||
|
dim path
|
||||||
|
if section.item("IsRelative") = "0" then
|
||||||
|
path = section.item("Path")
|
||||||
|
else
|
||||||
|
path = fso.buildPath(userDataFolderPath, section.item("Path"))
|
||||||
|
end if
|
||||||
|
if section.exists("Default") then
|
||||||
|
defaultProfileName = name
|
||||||
|
end if
|
||||||
|
if strComp(left(ourPath, len(path)), path, vbTextCompare) = 0 then
|
||||||
|
forcedProfilePath = path
|
||||||
|
end if
|
||||||
|
profilePaths.item(name) = path
|
||||||
|
end if
|
||||||
|
next
|
||||||
|
|
||||||
|
' and look what situation we're in
|
||||||
|
if len(forcedProfilePath) > 0 then
|
||||||
|
' running from within a profile -> use that one
|
||||||
|
getProfileFolderPath = forcedProfilePath
|
||||||
|
elseif profilePaths.count = 1 then
|
||||||
|
' just one profile found -> use it
|
||||||
|
getProfileFolderPath = profilePaths.items()(0)
|
||||||
|
else
|
||||||
|
' more than one profile found -> ask which one to use
|
||||||
|
do
|
||||||
|
dim prompt: prompt = "Which profile would you like to update ShadowFox in?"
|
||||||
|
dim profileName
|
||||||
|
dim profileChosen: profileChosen = true
|
||||||
|
for each profileName in profilePaths.keys()
|
||||||
|
prompt = prompt & vbNewLine & profileName & ": """ & profilePaths.item(profileName) & """"
|
||||||
|
next
|
||||||
|
dim chosenProfileName: chosenProfileName = trim(inputBox(prompt, "ShadowFox updater", defaultProfileName))
|
||||||
|
if len(chosenProfileName) = 0 then
|
||||||
|
getProfileFolderPath = ""
|
||||||
|
else
|
||||||
|
if profilePaths.exists(chosenProfileName) then
|
||||||
|
getProfileFolderPath = profilePaths.item(chosenProfileName)
|
||||||
|
else
|
||||||
|
' illegal one -> tell
|
||||||
|
call msgbox("The profile """ & chosenProfileName & """ doesn't exist; please select one from the list.", vbOKOnly & vbExclamation, "ShadowFox updater")
|
||||||
|
profileChosen = false
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
loop while not profileChosen
|
||||||
|
end if
|
||||||
|
end function
|
||||||
|
|
||||||
|
' gets the version of the given updater file
|
||||||
|
' return "" if not found
|
||||||
|
function getUpdaterVersion(updaterSourceCode)
|
||||||
|
regEx.pattern = "' version: (.*)"
|
||||||
|
dim matches: set matches = regEx.execute(updaterSourceCode)
|
||||||
|
if matches.count > 0 then
|
||||||
|
getUpdaterVersion = matches(0).subMatches(0)
|
||||||
|
else
|
||||||
|
getUpdaterVersion = ""
|
||||||
|
end if
|
||||||
|
end function
|
||||||
|
|
||||||
|
' gets the latest version of the updater
|
||||||
|
' returns if a newer version was installed
|
||||||
|
function getLatestUpdater(updaterFilePath)
|
||||||
|
' download the source of the latest updater
|
||||||
|
getLatestUpdater = false
|
||||||
|
dim latestSource
|
||||||
|
if downloadFile(updaterFileURL, latestSource) then
|
||||||
|
' done -> extract it's version
|
||||||
|
dim latestVersion: latestVersion = getUpdaterVersion(latestSource)
|
||||||
|
|
||||||
|
' extract our version
|
||||||
|
dim ourVersion: ourVersion = getUpdaterVersion(readFileContent(updaterFilePath))
|
||||||
|
|
||||||
|
' and see if there is a newer version available
|
||||||
|
if latestVersion > ourVersion then
|
||||||
|
' yes -> replace us with it
|
||||||
|
dim updaterPath: updaterPath = fso.getParentFolderName(updaterFilePath)
|
||||||
|
call backupFile(updaterFilePath, updaterPath)
|
||||||
|
call writeFileContent(updaterFilePath, latestSource)
|
||||||
|
getLatestUpdater = true
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
' determine where the files need to go
|
|
||||||
dim chromeFolderPath: chromeFolderPath = fso.buildPath(fso.getParentFolderName(wscript.scriptFullName), "chrome")
|
' ensure we're up-to-date
|
||||||
|
dim ourPath: ourPath = wscript.scriptFullName
|
||||||
|
if getLatestUpdater(ourPath) then
|
||||||
|
' we weren't, but are now -> tell we're going to run it
|
||||||
|
call msgbox("There is a new updater script available online. Your old version has been backed up, and the new one has been downloaded and has replaced this one. It will now be executed instead.", vbOKOnly, "ShadowFox updater")
|
||||||
|
call shell.run("""" & ourPath & """", , false)
|
||||||
|
else
|
||||||
|
' we are -> look which profile folder to update
|
||||||
|
dim profileFolderPath: profileFolderPath = getProfileFolderPath()
|
||||||
|
if len(profileFolderPath) > 0 then
|
||||||
|
' done -> determine where the files need to go
|
||||||
|
dim chromeFolderPath: chromeFolderPath = fso.buildPath(profileFolderPath, "chrome")
|
||||||
|
dim backupFolderPath: backupFolderPath = fso.buildPath(profileFolderPath, "chrome_backups")
|
||||||
dim chromeFilePath: chromeFilePath = fso.buildPath(chromeFolderPath, "userChrome.css")
|
dim chromeFilePath: chromeFilePath = fso.buildPath(chromeFolderPath, "userChrome.css")
|
||||||
dim contentFilePath: contentFilePath = fso.buildPath(chromeFolderPath, "userContent.css")
|
dim contentFilePath: contentFilePath = fso.buildPath(chromeFolderPath, "userContent.css")
|
||||||
dim customizationsFolderPath: customizationsFolderPath = fso.buildPath(chromeFolderPath, "ShadowFox_customization")
|
dim customizationsFolderPath: customizationsFolderPath = fso.buildPath(chromeFolderPath, "ShadowFox_customization")
|
||||||
|
@ -129,19 +316,7 @@ dim internalUUIDsFilePath: internalUUIDsFilePath = fso.buildPath(customizationsF
|
||||||
dim chromeCustomizationsFilePath: chromeCustomizationsFilePath = fso.buildPath(customizationsFolderPath, "userChrome_customization.css")
|
dim chromeCustomizationsFilePath: chromeCustomizationsFilePath = fso.buildPath(customizationsFolderPath, "userChrome_customization.css")
|
||||||
dim contentCustomizationsFilePath: contentCustomizationsFilePath = fso.buildPath(customizationsFolderPath, "userContent_customization.css")
|
dim contentCustomizationsFilePath: contentCustomizationsFilePath = fso.buildPath(customizationsFolderPath, "userContent_customization.css")
|
||||||
|
|
||||||
' ensure the files & folders are present, creating empty files as placeholders for users to customize
|
' and ask if we may continue
|
||||||
if not fso.folderExists(chromeFolderPath) then
|
|
||||||
call fso.createFolder(chromeFolderPath)
|
|
||||||
end if
|
|
||||||
if not fso.folderExists(customizationsFolderPath) then
|
|
||||||
call fso.createFolder(customizationsFolderPath)
|
|
||||||
end if
|
|
||||||
dim colorOverrides: colorOverrides = processCustomizationFile(colorOverridesFilePath)
|
|
||||||
dim internalUUIDs: internalUUIDs = processCustomizationFile(internalUUIDsFilePath)
|
|
||||||
dim chromeCustomizations: chromeCustomizations = processCustomizationFile(chromeCustomizationsFilePath)
|
|
||||||
dim contentCustomizations: contentCustomizations = processCustomizationFile(contentCustomizationsFilePath)
|
|
||||||
|
|
||||||
' ask if we may continue
|
|
||||||
dim prompt: prompt = "Updating userContent.css and userChrome.css for Firefox profile:" & vbNewLine & chromeFolderPath & vbNewLine
|
dim prompt: prompt = "Updating userContent.css and userChrome.css for Firefox profile:" & vbNewLine & chromeFolderPath & vbNewLine
|
||||||
if fso.fileExists(contentFilePath) then
|
if fso.fileExists(contentFilePath) then
|
||||||
prompt = prompt & vbNewLine & _
|
prompt = prompt & vbNewLine & _
|
||||||
|
@ -161,23 +336,31 @@ if vbNo = msgBox(prompt & vbSection & "Continue?", vbYesNo + vbDefaultButton2 +
|
||||||
' no -> tell
|
' no -> tell
|
||||||
call msgBox("Process aborted.", vbOKOnly, "ShadowFox updater")
|
call msgBox("Process aborted.", vbOKOnly, "ShadowFox updater")
|
||||||
else
|
else
|
||||||
' yes -> backup any existing files
|
' yes -> ensure the folders are present
|
||||||
|
if not fso.folderExists(chromeFolderPath) then
|
||||||
|
call fso.createFolder(chromeFolderPath)
|
||||||
|
end if
|
||||||
|
if not fso.folderExists(customizationsFolderPath) then
|
||||||
|
call fso.createFolder(customizationsFolderPath)
|
||||||
|
end if
|
||||||
|
|
||||||
|
' backup any existing files
|
||||||
prompt = "Installing new ShadowFox files."
|
prompt = "Installing new ShadowFox files."
|
||||||
if fso.fileExists(contentFilePath) then
|
if fso.fileExists(contentFilePath) then
|
||||||
prompt = prompt & vbNewLine & _
|
prompt = prompt & vbNewLine & _
|
||||||
"Your previous userContent.css file was backed up: " & backupFile(chromeFolderPath, contentFilePath, "userContent")
|
"Your previous userContent.css file was backed up: " & backupFile(contentFilePath, backupFolderPath)
|
||||||
end if
|
end if
|
||||||
if fso.fileExists(chromeFilePath) then
|
if fso.fileExists(chromeFilePath) then
|
||||||
prompt = prompt & vbNewLine & _
|
prompt = prompt & vbNewLine & _
|
||||||
"Your previous userChrome.css file was backed up: " & backupFile(chromeFolderPath, chromeFilePath, "userChrome")
|
"Your previous userChrome.css file was backed up: " & backupFile(chromeFilePath, backupFolderPath)
|
||||||
end if
|
end if
|
||||||
|
|
||||||
' download the latest versions
|
' download the latest versions
|
||||||
dim allOK
|
dim allOK
|
||||||
allOK = true
|
allOK = true
|
||||||
if _
|
if _
|
||||||
not downloadFile(chromeFileURL, chromeFilePath) or _
|
not downloadAndSaveFile(chromeFileURL, chromeFilePath) or _
|
||||||
not downloadFile(contentFileURL, contentFilePath) _
|
not downloadAndSaveFile(contentFileURL, contentFilePath) _
|
||||||
then
|
then
|
||||||
' error downloading -> tell
|
' error downloading -> tell
|
||||||
prompt = prompt & vbSection & _
|
prompt = prompt & vbSection & _
|
||||||
|
@ -193,6 +376,7 @@ else
|
||||||
dim contentFileContent: contentFileContent = readFileContent(contentFilePath)
|
dim contentFileContent: contentFileContent = readFileContent(contentFilePath)
|
||||||
|
|
||||||
' do any extension UUID replacements
|
' do any extension UUID replacements
|
||||||
|
dim internalUUIDs: internalUUIDs = processCustomizationFile(internalUUIDsFilePath)
|
||||||
if len(internalUUIDs) = 0 then
|
if len(internalUUIDs) = 0 then
|
||||||
prompt = prompt & vbSection & _
|
prompt = prompt & vbSection & _
|
||||||
"You have not defined any internal UUIDs for webextensions." & vbNewLine & _
|
"You have not defined any internal UUIDs for webextensions." & vbNewLine & _
|
||||||
|
@ -213,6 +397,7 @@ else
|
||||||
end if
|
end if
|
||||||
|
|
||||||
' process any color overrides
|
' process any color overrides
|
||||||
|
dim colorOverrides: colorOverrides = processCustomizationFile(colorOverridesFilePath)
|
||||||
if len(colorOverrides) = 0 then
|
if len(colorOverrides) = 0 then
|
||||||
prompt = prompt & vbSection & _
|
prompt = prompt & vbSection & _
|
||||||
"You are using the default colors set by ShadowFox." & vbNewLine & _
|
"You are using the default colors set by ShadowFox." & vbNewLine & _
|
||||||
|
@ -227,6 +412,7 @@ else
|
||||||
end if
|
end if
|
||||||
|
|
||||||
' add on any overrides
|
' add on any overrides
|
||||||
|
dim contentCustomizations: contentCustomizations = processCustomizationFile(contentCustomizationsFilePath)
|
||||||
if len(contentCustomizations) = 0 then
|
if len(contentCustomizations) = 0 then
|
||||||
prompt = prompt & vbSection & _
|
prompt = prompt & vbSection & _
|
||||||
"You do not have any custom userContent.css tweaks." & vbNewLine & _
|
"You do not have any custom userContent.css tweaks." & vbNewLine & _
|
||||||
|
@ -236,6 +422,7 @@ else
|
||||||
prompt = prompt & vbSection & _
|
prompt = prompt & vbSection & _
|
||||||
"Your custom userContent.css tweaks have been applied."
|
"Your custom userContent.css tweaks have been applied."
|
||||||
end if
|
end if
|
||||||
|
dim chromeCustomizations: chromeCustomizations = processCustomizationFile(chromeCustomizationsFilePath)
|
||||||
if len(chromeCustomizations) = 0 then
|
if len(chromeCustomizations) = 0 then
|
||||||
prompt = prompt & vbSection & _
|
prompt = prompt & vbSection & _
|
||||||
"You do not have any custom userChrome.css tweaks." & vbNewLine & _
|
"You do not have any custom userChrome.css tweaks." & vbNewLine & _
|
||||||
|
@ -261,3 +448,5 @@ else
|
||||||
' and tell we're done
|
' and tell we're done
|
||||||
call msgBox(prompt, iif(allOK, vbInformation, vbExclamation), "ShadowFox updater")
|
call msgBox(prompt, iif(allOK, vbInformation, vbExclamation), "ShadowFox updater")
|
||||||
end if
|
end if
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
|
Loading…
Reference in New Issue