This script is a template of package launcher.
It gathers many functions allowing to install a package using generic VBScript functions:
- Check if a package is installed (MSI) using the registry
- Uninstall a package if installed
- EXE silent uninstallation
- Single MSI installation
- MSI + MST installation
- EXE silent installation
- EXE + ISS response file silent installation
- Importation of REG files
- File copy
- Folder copy
- Run Command
- Grant NTFS permission to files and foldersAdditional functions are also available.
1. Package Launcher Script
'------------------------------------------------------ 'INSTALLATION SCRIPT '------------------------------------------------------ 'Date : 'Author : '------------------------------------------------------ 'Package Information PACKAGE_NAME = "" 'Declarations Const LOG_PATH = "C:\Logs" Dim LogFile, MsiExitCode, ExeExitCode, RegExitCode, CopyExitCode, CmdExitCode, SecExitCode, InstallCheck Set Fso = CreateObject("Scripting.FileSystemObject") Set WshNetwork = WScript.CreateObject("WScript.Network") Set WshShell = Wscript.CreateObject("Wscript.Shell") Set WsProcEnv = WshShell.Environment("Process") CompName = WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%") Main '------------------------------------------------------ 'MAIN SUB '------------------------------------------------------ Sub Main On Error Resume Next If Not Fso.FolderExists(LOG_PATH) Then Fso.CreateFolder LOG_PATH End If LogFileName = LOG_PATH & "\" & PACKAGE_NAME & "_flag.log" Set LogFile = Fso.OpenTextFile(LogFileName, 8, True) LogFile.WriteLine Now & " : Starting Installation Script : " & PACKAGE_NAME LogFile.WriteLine "" 'CHECK IF INSTALLED 'Check if a key (usually ProductCode) is present under Microsoft\Windows\CurrentVersion\Uninstall for both 32 and 64 bit (Return InstallCheck = TRUE or FALSE) CHECKSTR = "" CheckIfInstalled CHECKSTR 'MSI UNINSTALLATION 'Parameter is the ProductCode of the msi to uninstall : {......................}. Uninstall is launched only if the previous CheckIfInstalled is TRUE If InstallCheck Then MSIPRODUCTCODE = "" UninstallMSI MSIPRODUCTCODE End If 'EXE SILENT UNINSTALLATION 'Parameters are the exe file name (use folder\filename if necessary) and arguments. Uninstall is launched only if the previous CheckIfInstalled is TRUE If InstallCheck Then EXENAME = "" EXEARGS = "" UninstallEXE EXENAME, EXEARGS End If 'SINGLE MSI INSTALLATION 'Parameter is the msi file name (use folder\filename if necessary) MSINAME = "" InstallMSI MSINAME 'MSI WITH MST INSTALLATION 'Parameter are the msi and the mst file names (use folder\filename if necessary) MSINAME = "" MSTNAME = "" InstallMSIwithMST MSINAME, MSTNAME 'EXE SILENT INSTALL 'Parameters are the exe file name (use folder\filename if necessary) and arguments EXENAME = "" EXEARGS = "" SilentInstall EXENAME, EXEARGS 'EXE SILENT INSTALL USING ISS RESPONSE FILE 'Parameters are the exe and the iss file names (use folder\filename if necessary) EXENAME = "" ISSNAME = "" SilentInstallWithISS EXENAME, ISSNAME 'REG IMPORTATION 'Parameter is the reg file name (use folder\filename if necessary) REGNAME = "" RegImport REGNAME 'FILE COPY 'Parameters are the file name (use folder\filename if necessary) and the destination folder with \ at the end FILENAME = "" TARGETFOLDER = "" FileCopy FILENAME, TARGETFOLDER 'FOLDER COPY 'Parameters are the folders name SOURCEFOLDER = "" TARGETFOLDER = "" FileCopy SOURCEFOLDER, TARGETFOLDER 'COMMAND RUN 'Parameter is the command to run CMDTORUN = "" RunCommandLine CMDTORUN 'GRANT PERMISSION 'No parameter, the sub must be edited with the folders and the files to unblock GrantPermission LogFile.WriteLine Now & " : Ending Installation Script : " & PACKAGE_NAME LogFile.WriteLine Now & " : " & PACKAGE_NAME & " installation completed successfully" LogFile.WriteLine "" LogFile.Close WScript.Quit End Sub '------------------------------------------------------ 'CheckIfInstalled '------------------------------------------------------ Sub CheckIfInstalled(vCHECKSTR) LogFile.WriteLine Now & " : Starting CheckIfInstalled : " & vCHECKSTR InstallCheck = FALSE InstallCheck_x86 = FALSE InstallCheck_x64 = FALSE Const HKLM = &h80000002 'Check 32-bit registry '********************* Set Ctx32 = CreateObject("WbemScripting.SWbemNamedValueSet") Ctx32.Add "__ProviderArchitecture", 32 Ctx32.Add "__RequiredArchitecture", TRUE Set Locator32 = CreateObject("Wbemscripting.SWbemLocator") Set Services32 = Locator32.ConnectServer("","root\default","","",,,,Ctx32) Set StdRegProv32 = Services32.Get("StdRegProv") Set Inparams32 = StdRegProv32.Methods_("EnumKey").Inparameters Inparams32.Hdefkey = HKLM Inparams32.Ssubkeyname = "Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" Set Outparams32 = StdRegProv32.ExecMethod_("EnumKey", Inparams32,,Ctx32) For Each SubKey32 In Outparams32.snames If SubKey32 = vCHECKSTR Then InstallCheck_x86 = TRUE End If Next If (InstallCheck_x86 = TRUE) Then InstallCheck = TRUE LogFile.WriteLine Now & " : " & vCHECKSTR & " is present in 32-bit registry" Else LogFile.WriteLine Now & " : " & vCHECKSTR & " is NOT present in 32-bit registry" End If 'Check 64-bit registry if not found in 32-bit '******************************************** If (InstallCheck = FALSE) Then Set Ctx64 = CreateObject("WbemScripting.SWbemNamedValueSet") Ctx64.Add "__ProviderArchitecture", 64 Ctx64.Add "__RequiredArchitecture", TRUE Set Locator64 = CreateObject("Wbemscripting.SWbemLocator") Set Services64 = Locator64.ConnectServer("","root\default","","",,,,Ctx64) Set StdRegProv64 = Services64.Get("StdRegProv") Set Inparams64 = StdRegProv64.Methods_("EnumKey").Inparameters Inparams64.Hdefkey = HKLM Inparams64.Ssubkeyname = "Software\Microsoft\Windows\CurrentVersion\Uninstall" Set Outparams64 = StdRegProv64.ExecMethod_("EnumKey", Inparams64,,Ctx64) For Each SubKey64 In Outparams64.snames If SubKey64 = vCHECKSTR Then InstallCheck_x64 = TRUE End If Next If (InstallCheck_x64 = TRUE) Then InstallCheck = TRUE LogFile.WriteLine Now & " : " & vCHECKSTR & " is present in 64-bit registry" Else LogFile.WriteLine Now & " : " & vCHECKSTR & " is NOT present in 64-bit registry" End If End If End Sub Sub UninstallMSI(vMSIPRODUCTCODE) LogFile.WriteLine Now & " : Command line launched : msiexec /x " & vMSIPRODUCTCODE & " /qn /L*xv " & LOG_PATH & "\" & vMSIPRODUCTCODE & "-uninstall_msi.log" MsiExitCode = WshShell.Run("msiexec /x " & vMSIPRODUCTCODE & " /qn /L*xv " & LOG_PATH & "\" & vMSIPRODUCTCODE & "-uninstall_msi.log", 0, TRUE) If Err.Number <> 0 Then ErrorLogging "UninstallMSI GeneralError", Err.Number, Err.Description End If If MsiExitCode <> 0 And MsiExitCode <> 3010 Then ErrorLogging "UninstallMSI MsiExitCode", MsiExitCode, "Error MSI" End If LogFile.WriteLine Now & " : Ending UninstallMSI : " & vMSIPRODUCTCODE LogFile.WriteLine "" End Sub '------------------------------------------------------ 'UninstallEXE '------------------------------------------------------ Sub UninstallEXE(vEXENAME, vEXEARGS) LogFile.WriteLine Now & " : Starting UninstallEXE : " & vEXENAME LogFile.WriteLine Now & " : Command line launched : """ & vEXENAME & """ " & vEXEARGS ExeExitCode = WshShell.Run(""""& vEXENAME & """ " & vEXEARGS, 0, TRUE) If Err.Number <> 0 Then ErrorLogging "UninstallEXE GeneralError", Err.Number, Err.Description End If If ExeExitCode <> 0 And ExeExitCode <> 3010 Then ErrorLogging "UninstallEXE ExeExitCode", ExeExitCode, "Error EXE" End If LogFile.WriteLine Now & " : Ending UninstallEXE : " & vEXENAME LogFile.WriteLine "" End Sub '------------------------------------------------------ 'InstallMSI '------------------------------------------------------ Sub InstallMSI(vMSINAME) arrLog = Split(vMSINAME, "\") intIndex = Ubound(arrLog) LOGNAME=arrLog(intIndex) LogFile.WriteLine Now & " : Starting InstallMSI : " & vMSINAME LogFile.WriteLine Now & " : Command line launched : msiexec /i """ & vMSINAME & """ /qn /L*xv """ & LOG_PATH & "\" & LOGNAME & "-install_msi.log""" MsiExitCode = WshShell.Run("msiexec /i """ & vMSINAME & """ /qn /L*xv """ & LOG_PATH & "\" & LOGNAME & "-install_msi.log""", 0, TRUE) If Err.Number <> 0 Then ErrorLogging "InstallMSI GeneralError", Err.Number, Err.Description End If If MsiExitCode <> 0 AND MsiExitCode <> 3010 Then ErrorLogging "InstallMSI MsiExitCode", MsiExitCode, "Error MSI" End If LogFile.WriteLine Now & " : Ending InstallMSI : " & vMSINAME LogFile.WriteLine "" End Sub '------------------------------------------------------ 'InstallMSIwithMST '------------------------------------------------------ Sub InstallMSIwithMST(vMSINAME, vMSTNAME) arrLog = Split(vMSINAME, "\") intIndex = Ubound(arrLog) LOGNAME=arrLog(intIndex) LogFile.WriteLine Now & " : Starting InstallMSIwithMST : " & vMSINAME & " + " & vMSTNAME LogFile.WriteLine Now & " : Command line launched : msiexec /i """ & vMSINAME & """ TRANSFORMS=""" & vMSTNAME & """ /qn /L*xv """ & LOG_PATH & "\" & LOGNAME & "-install_msi.log""" MsiExitCode = WshShell.Run("msiexec /i """ & vMSINAME & """ TRANSFORMS=""" & vMSTNAME & """ /qn /L*xv """ & LOG_PATH & "\" & LOGNAME & "-install_msi.log""", 0, TRUE) If Err.Number <> 0 Then ErrorLogging "InstallMSIwithMST GeneralError", Err.Number, Err.Description End If If MsiExitCode <> 0 AND MsiExitCode <> 3010 Then ErrorLogging "InstallMSIwithMST MsiExitCode", MsiExitCode, "Error MSI" End If LogFile.WriteLine Now & " : Ending InstallMSIwithMST : " & vMSINAME & " + " & vMSTNAME LogFile.WriteLine "" End Sub '------------------------------------------------------ 'SilentInstall '------------------------------------------------------ Sub SilentInstall(vEXENAME, vEXEARGS) LogFile.WriteLine Now & " : Starting SilentInstall : " & vEXENAME LogFile.WriteLine Now & " : Command line launched : """& vEXENAME & """ " & vEXEARGS ExeExitCode = WshShell.Run(""""& vEXENAME & """ " & vEXEARGS, 0, TRUE) If Err.Number <> 0 Then ErrorLogging "SilentInstall GeneralError", Err.Number, Err.Description End If If ExeExitCode <> 0 AND ExeExitCode <> 3010 Then ErrorLogging "SilentInstall ExeExitCode", ExeExitCode, "Error EXE" End If LogFile.WriteLine Now & " : Ending SilentInstall : " & vEXENAME LogFile.WriteLine "" End Sub '------------------------------------------------------ 'SilentInstallWithISS '------------------------------------------------------ Sub SilentInstallWithISS(vEXENAME, vISSNAME) arrLog = Split(vEXENAME, "\") intIndex = Ubound(arrLog) LOGNAME=arrLog(intIndex) LogFile.WriteLine Now & " : Starting SilentInstallWithISS : " & vEXENAME & " + " & vISSNAME LogFile.WriteLine Now & " : Command line launched : """& vEXENAME & """ -s -f1""" & vISSNAME & """ -f2""" & LOG_PATH & "\" & PACKAGE_NAME & "_" & LOGNAME & "-install_exe.log""" ExeExitCode = WshShell.Run("""" & WshShell.CurrentDirectory & "\" & vEXENAME & """ -s -f1""" & WshShell.CurrentDirectory & "\" & vISSNAME & """ -f2""" & LOG_PATH & "\" & PACKAGE_NAME & "_" & LOGNAME & "-install_exe.log""", 0, TRUE) If Err.Number <> 0 Then ErrorLogging "SilentInstallWithISS GeneralError", Err.Number, Err.Description End If If ExeExitCode <> 0 AND ExeExitCode <> 3010 Then ErrorLogging "SilentInstallWithISS ExeExitCode", ExeExitCode, "Error EXE" End If LogFile.WriteLine Now & " : Ending SilentInstallWithISS : " & vEXENAME & " + " & vISSNAME LogFile.WriteLine "" End Sub '------------------------------------------------------ 'RegImport '------------------------------------------------------ Sub RegImport(vREGNAME) LogFile.WriteLine Now & " : Starting RegImport : " & vREGNAME LogFile.WriteLine Now & " : Command line launched : regedit.exe /s " & vREGNAME RegExitCode = WshShell.Run("regedit.exe /s " & vREGNAME, 0, TRUE) If Err.Number <> 0 Then ErrorLogging "RegImport GeneralError", Err.Number, Err.Description End If If RegExitCode <> 0 And RegExitCode <> 3010 Then ErrorLogging "RegImport RegExitCode", RegExitCode, "Error REG" End If LogFile.WriteLine Now & " : Ending RegImport : " & vREGNAME LogFile.WriteLine "" End Sub '------------------------------------------------------ 'FileCopy '------------------------------------------------------ Sub FileCopy(vFILENAME, vTARGETFOLDER) LogFile.WriteLine Now & " : Starting FileCopy : " & vFILENAME vTARGETFOLDER = WshShell.ExpandEnvironmentStrings(vTARGETFOLDER) If Not Fso.FolderExists(vTARGETFOLDER) Then Fso.CreateFolder vTARGETFOLDER End If LogFile.WriteLine Now & " : Command line launched : Fso.CopyFile(" & vFILENAME & "," & vTARGETFOLDER & vFILENAME &",TRUE)" CopyExitCode = Fso.CopyFile(vFILENAME, vTARGETFOLDER & vFILENAME, TRUE) If Err.Number <> 0 Then ErrorLogging "FileCopy GeneralError", Err.Number, Err.Description End If If CopyExitCode <> 0 And CopyExitCode <> 3010 Then ErrorLogging "FileCopy CopyExitCode", CopyExitCode, "Error COPY" End If LogFile.WriteLine Now & " : Ending FileCopy : " & vFILENAME LogFile.WriteLine "" End Sub '------------------------------------------------------ 'FolderCopy '------------------------------------------------------ Sub FolderCopy(vSOURCEFOLDER, vTARGETFOLDER) LogFile.WriteLine Now & " : Starting FolderCopy : " & vSOURCEFOLDER vSOURCEFOLDER = WshShell.ExpandEnvironmentStrings(vSOURCEFOLDER) vTARGETFOLDER = WshShell.ExpandEnvironmentStrings(vTARGETFOLDER) If Not Fso.FolderExists(vTARGETFOLDER) Then Fso.CreateFolder vTARGETFOLDER End If LogFile.WriteLine Now & " : Command line launched : Fso.CopyFolder " & vSOURCEFOLDER & ", " & vTARGETFOLDER CopyExitCode = Fso.CopyFolder(vSOURCEFOLDER, vTARGETFOLDER) If Err.Number <> 0 Then ErrorLogging "FolderCopy GeneralError", Err.Number, Err.Description End If If CopyExitCode <> 0 And CopyExitCode <> 3010 Then ErrorLogging "FolderCopy CopyExitCode", CopyExitCode, "Error COPY" End If LogFile.WriteLine Now & " : Ending FolderCopy : " & vSOURCEFOLDER LogFile.WriteLine "" End Sub '------------------------------------------------------ 'RunCommandLine '------------------------------------------------------ Sub RunCommandLine(vCMDTORUN) LogFile.WriteLine Now & " : Starting RunCommandLine : " & vCMDTORUN vCMDTORUN = WshShell.ExpandEnvironmentStrings(vCMDTORUN) LogFile.WriteLine Now & " : Command line launched : " & vCMDTORUN CmdExitCode = WshShell.Run("cmd.exe /C " & vCMDTORUN, 0, TRUE) If Err.Number <> 0 Then ErrorLogging "RunCommandLine GeneralError", Err.Number, Err.Description End If If CmdExitCode <> 0 And CmdExitCode <> 3010 Then ErrorLogging "RunCommandLine CmdExitCode", CmdExitCode, "Error COMMAND" End If LogFile.WriteLine Now & " : Ending RunCommandLine : " & vCMDTORUN LogFile.WriteLine "" End Sub '------------------------------------------------------ 'GrantPermission '------------------------------------------------------ Sub GrantPermission LogFile.WriteLine Now & " : Starting GrantPermission" 'INF file creation Dim FileCreation Set FileCreation = Fso.CreateTextFile(LOG_PATH & "\" & PACKAGE_NAME &"-Security.inf", True) FileCreation.WriteLine("[Unicode]") FileCreation.WriteLine("Unicode=yes") FileCreation.WriteLine("[Version]") FileCreation.WriteLine("signature=" & chr(34) & "$CHICAGO$" & chr(34)) FileCreation.WriteLine("Revision=1") FileCreation.WriteLine("[File Security]") FileCreation.WriteLine(chr(34) & "%ProgramFiles%\Soft\Folder" & chr(34) & ",0," & chr(34) & "D:AR(A;OICI;0x1301bf;;;BU)" & chr(34)) FileCreation.WriteLine(chr(34) & "%SystemRoot%\system32\File" & chr(34) & ",0," & chr(34) & "D:AR(A;;0x1301bf;;;BU)" & chr(34)) FileCreation.Close 'INF file execution Dim ExecuteInf ExecuteInf = "secedit /configure /DB " & LOG_PATH & "\" & PACKAGE_NAME &"-Security.edb" & " /CFG " & LOG_PATH & "\" & PACKAGE_NAME & "-Security.inf /areas FILESTORE /log " & LOG_PATH & "\" & PACKAGE_NAME & "-Security.log" SecExitCode = mobjWsShell.Run(ExecuteInf, 0, TRUE) 'INF file removal Fso.DeleteFile(LOG_PATH & "\" & PACKAGE_NAME & "-Security.inf") If Err.Number <> 0 Then ErrorLogging "GrantPermission GeneralError", Err.Number, Err.Description End If If SecExitCode <> 0 And SecExitCode <> 3010 Then ErrorLogging "GrantPermission SecExitCode", SecExitCode, "Error SECURITY" End If LogFile.WriteLine Now & " : Ending GrantPermission" LogFile.WriteLine "" End Sub '------------------------------------------------------ 'ErrorLogging '------------------------------------------------------ Sub ErrorLogging(vSource, vErrorNb, vErrorDesc) LogFile.WriteLine Now & " : " & PACKAGE_NAME & " encounter an error" WshShell.LogEvent 2, "ERROR - " & vSource & " - " & vErrorNb & " - " & vErrorDesc LogFile.WriteLine Now & " : ERROR - " & vSource & " - " & vErrorNb & " - " & vErrorDesc LogFile.Close WScript.Quit(vErrorNb) End Sub
.
.
2. Additional Scripts
2.1 Check OS Type
Dim msOSType, process_architecture 'CHECK OS TYPE CheckOSType If (msOSType="x64") Then 'x64-bit commands… End If If (msOSType="x86") Then 'x86-bit commands… End If '------------------------------------------------------ 'CheckOSType '------------------------------------------------------ Sub CheckOSType() LogFile.WriteLine Now & " : Starting CheckOSType" process_architecture= WsProcEnv("PROCESSOR_ARCHITECTURE") If process_architecture = "x86" Then msOSType= WsProcEnv("PROCESSOR_ARCHITEW6432") If msOSType = "" Then msOSType = "x86" LogFile.WriteLine Now & " : 32 bit OS detected " & Now End if Else msOSType = "x64" LogFile.WriteLine Now & " : 64 bit OS detected " & Now End If LogFile.WriteLine Now & " : Ending CheckOSType" LogFile.WriteLine "" End Sub
.
.
2.2 MSU Installation
Dim MsuExitCode 'MSU INSTALLATION 'Parameter is the msu file name (use folder\filename if necessary) MSUNAME = "" InstallMSU MSUNAME '------------------------------------------------------ 'InstallMSU '------------------------------------------------------ Sub InstallMSU(vMSUNAME) arrLog = Split(vMSUNAME, "\") intIndex = Ubound(arrLog) LOGNAME=arrLog(intIndex) LogFile.WriteLine Now & " : Starting InstallMSU : " & vMSUNAME LogFile.WriteLine Now & " : Command line launched : wusa.exe """ & vMSUNAME & """ /quiet /norestart /log:""" & LOG_PATH & "\" & LOGNAME & "-install_msu.log""" MsuExitCode = WshShell.Run("wusa.exe """ & vMSUNAME & """ /quiet /norestart /log:""" & LOG_PATH & "\" & LOGNAME & "-install_msu.log""", 0, TRUE) If Err.Number <> 0 Then ErrorLogging "InstallMSU GeneralError", Err.Number, Err.Description End If If MsuExitCode <> 0 AND MsuExitCode <> 3010 Then ErrorLogging "InstallMSU MsuExitCode", MsuExitCode, "Error MSU" End If LogFile.WriteLine Now & " : Ending InstallMSU : " & vMSUNAME LogFile.WriteLine "" End Sub
.
.
2.3 Services Stop and Start
'STOP SERVICE 'Parameter is the service name SERVICENAME = "" StopService SERVICENAME 'START SERVICE 'Parameter is the service name SERVICENAME = "" StartService SERVICENAME '------------------------------------------------------ 'StopService '------------------------------------------------------ Sub StopService(vSERVICENAME) LogFile.WriteLine Now & " : Starting StopService : " & vSERVICENAME Dim lobjWMIService, lcolListOfServices, lobjService Set lobjWMIService = GetObject("winmgmts:\\" & CompName & "\root\CimV2") Set lcolListOfServices = lobjWMIService.ExecQuery ("Select * From Win32_Service Where Name ='" & vSERVICENAME & "'") For Each lobjService in lcolListOfServices If lobjService.Started Then lobjService.StopService End If lobjService.ChangeStartMode("Disabled") Wscript.Sleep 5000 Next LogFile.WriteLine Now & " : Ending StopService : " & vSERVICENAME LogFile.WriteLine "" End Sub '------------------------------------------------------ 'StartService '------------------------------------------------------ Sub StartService(vSERVICENAME) LogFile.WriteLine Now & " : Starting StartService : " & vSERVICENAME Dim lobjWMIService, lcolListOfServices, lobjService Set lobjWMIService = GetObject("winmgmts:\\" & CompName & "\root\CimV2") Set lcolListOfServices = lobjWMIService.ExecQuery ("Select * From Win32_Service Where Name ='" & vSERVICENAME & "'") For Each lobjService in lcolListOfServices If lobjService.Stopped Then lobjService.StartService End If lobjService.ChangeStartMode("Manual") Wscript.Sleep 5000 Next LogFile.WriteLine Now & " : Ending StartService : " & vSERVICENAME LogFile.WriteLine "" End Sub
.
.
2.4 Taskkill
'TASKKILL 'Parameter is the exe file to kill TASKNAME = "" Run_Taskkill TASKNAME '------------------------------------------------------ 'Run_Taskkill '------------------------------------------------------ Sub Run_Taskkill(vTASKNAME) LogFile.WriteLine Now & " : Starting Run_Taskkill : " & vTASKNAME LogFile.WriteLine Now & " : Command line launched : cmd.exe /C taskkill /im """ & vTASKNAME & """ /f" CmdExitCode = WshShell.Run("cmd.exe /C taskkill /im """ & vTASKNAME & """ /f", 0, TRUE) If Err.Number <> 0 Then ErrorLogging "Run_Taskkill GeneralError", Err.Number, Err.Description End If LogFile.WriteLine Now & " : Ending Run_Taskkill : " & vTASKNAME LogFile.WriteLine "" End Sub
.