|
![]() |
| Update Hosts File |
This example shows how you can easily add and remove blocks of text from a text file. It adds a start and end marker to make identification of the inserted block easy.
It could easily be enhanced to have some soort of commit and rollback.
#define MarksStart [MyMsi.MM: AUTO-INSERTED-START] ;;Marks start of block in the hosts file
#define MarksEnd [MyMsi.MM: AUTO-INSERTED-END] ;;Marks end of block in the hosts file
#define MarksNewLine {NL}
#( '<$MarksNewLine>'
#define HostFileChanges
<$MarksNewLine><$MarksNewLine><$MarksNewLine>
<?Hash>##################<$MarksStart>################
<?Hash>
<?Hash> Do not insert new host entries in this block or alter records (update MSI source to correct faults)
<?Hash> Inserted at <?CompileTime>
<$MarksNewLine><$MarksNewLine><$MarksNewLine>
1.2.3.4 SillyHostName1
1.2.3.5 SillyHostName2
<?Hash>##################<$MarksEnd>##################
#)
<$VbsCa Binary="UpdateTcpipHostsFile.vbs">
const MaxNumberOfBlankLines = 5
<$VbsCaEntry "AddToHostsFile">
RemoveExisting()
AddAdditions()
<$/VbsCaEntry>
<$VbsCaEntry "RemoveFromHostsFile">
RemoveExisting()
<$/VbsCaEntry>
<?NewLine><?NewLine>
'===========================================================================
sub RemoveExisting()
'===========================================================================
CaDebug 2, "Removing any previously added entries from the hosts file..."
VbsCaLogInc 1
dim HostsFile : HostsFile = VbsCaPropertyGet("SystemFolder", "c:\winnt\system32\", "") & "Drivers\Etc\Hosts"
dim oFS : set oFS = CaMkObject("Scripting.FileSystemObject")
if not oFS.FileExists(HostsFile) then
;--- Nothing to undo --------------------------------------------
CaDebug 2, "No hosts file to remove entries from"
else
;--- Open Files -------------------------------------------------
CaDebug 2, "Hosts file exists, opening files"
dim TmpFile : TmpFile = CaGetEnv("TEMP", true) & "\NewHostsFile(RemoveExisting).txt"
CaDebug 2, "Temporary file: " & TmpFile
dim ReadStream : set ReadStream = oFS.OpenTextFile(HostsFile, ForReading)
dim WriteStream : set WriteStream = oFS.CreateTextFile(TmpFile, true)
dim CopyLines : CopyLines = true
dim DidRemove : DidRemove = false
dim BlankLineCnt: BlankLineCnt = 0
CaDebug 0, "Reading File"
VbsCaLogInc 1
do while ReadStream.AtEndOfStream <> true
;--- Read the line ------------------------------------------
dim ReadLine : ReadLine = ReadStream.ReadLine()
CaDebug 0, "LINE> " & ReadLine
VbsCaLogInc 1
;--- Copy all lines except those in previously copied block ---
if CopyLines then
;--- Not in a block, so see if we found the start -------
if instr(ReadLine, "<$MarksStart>") <> 0 then
;--- Found the start of the block -------------------
CaDebug 0, "Found the start of the block"
CopyLines = false
DidRemove = true
else
;--- Copy the line ----------------------------------
if ReadLine = "" then
;--- Have a blank line, just count (will drop trailing blank lines) ---
BlankLineCnt = BlankLineCnt + 1
else
;--- Output any queued up blank lines? ----------
dim i
for i = 1 to min(BlankLineCnt, MaxNumberOfBlankLines)
WriteStream.writeline("")
next
;--- Output the actual line ---------------------
WriteStream.writeline(ReadLine)
end if
end if
else
;--- In a block, so see if we found the end -------------
if instr(ReadLine, "<$MarksEnd>") <> 0 then
;--- Found the start of the block -------------------
CaDebug 0, "Found the end of the block"
CopyLines = true
end if
end if
;--- Restore indent -----------------------------------------
VbsCaLogInc -1
loop
VbsCaLogInc -1
;--- Finished Extraction ----------------------------------------
ReadStream.Close()
WriteStream.Close()
set ReadStream = Nothing
set WriteStream = Nothing
;--- Update Hosts File ------------------------------------------
if not DidRemove then
CaDebug 0, "Finished creating new host file, no changes so no need to copy over: " & HostsFile
else
CaDebug 0, "Finished creating new host file, so update: " & HostsFile
oFS.CopyFile TmpFile, HostsFile, true
end if
CaDebug 0, "Removal completed"
end if
VbsCaLogInc -1
set oFS = Nothing
end sub
<?NewLine><?NewLine>
'===========================================================================
function Min(x, y)
'===========================================================================
dim Tmp
if x < y then Tmp = x else Tmp = y
Min = Tmp
end function
<?NewLine><?NewLine>
'===========================================================================
sub AddAdditions()
'===========================================================================
CaDebug 2, "Adding new entries to the hosts file..."
VbsCaLogInc 1
dim Additions : Additions = replace("<$HostFileChanges>", "<$MarksNewLine>", vbCRLF)
dim HostsFile : HostsFile = VbsCaPropertyGet("SystemFolder", "c:\winnt\system32\", "") & "Drivers\Etc\Hosts"
dim oFS : set oFS = CaMkObject("Scripting.FileSystemObject")
if not oFS.FileExists(HostsFile) then
;--- Nothing to undo --------------------------------------------
CaDebug 2, "No hosts file, will create"
end if
CaDebug 2, "Append new host file lines"
dim Stream : set Stream = oFS.OpenTextFile(HostsFile, ForAppending, true)
Stream.WriteLine vBCRLF & Additions
Stream.close()
set Stream = Nothing
CaDebug 2, "Finished adding new host lines"
set oFS = Nothing
VbsCaLogInc -1
end sub
<$/VbsCa>
<$VbsCaSetup Binary="UpdateTcpipHostsFile.vbs" Entry="AddToHostsFile" Seq="InstallValidate-" CONDITION=^<$CONDITION_EXCEPT_UNINSTALL>^ Type="IMMEDIATE">
Note that the above works for 32 bit OS (to also handle 64 bit replace "SystemFolder" with "SYSTEM32").
![]() | ![]() |