MAKEMSI quickly and reliably creates MSI files in a non-programmatic way
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
[Bottom][Contents][Prev]: Unversioned files[Next]: ZIP Images for Directory Trees
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->Tips and Tricks->File and Directory->Update Hosts File

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">


Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: Unversioned files[Next]: ZIP Images for Directory Trees


MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Saturday November 19 2011 at 2:21pm
Visit MAKEMSI's Home Page
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.