Solved

Add 1 Line to a File at a Particular Point??

Posted on 2004-04-08
12
175 Views
Last Modified: 2010-05-02
I need to add one line, at a particular point (after a particular line) in a file, this file is called machine.config. This needs to be done on a number of machines in the network.

Basically the psuedo code would look something like:

'do for all the machines on the network BHW0 to BHW86
for n=0; n < 86; n++ {

    find file machine.config on machine BHn

    line_number = 0

    'Search through lines of file until particular line found
    do

        line_number++

    until ((line_number = num_of_lines_in_file) OR (content_at_line_number = "trust = medium"))

    'If line is found then add the new line and save
    if line_number < num_of_lines_in_file THEN
        add a line to the file
        save the file
    end if  

    }

}  

Very sorry in advance for the bad coding, I am not a programmer, I work in network support.

Is the above possible?

What language is best to use?

Any help would be much appreciated.

Thanks

Dan
0
Comment
Question by:options_technology
  • 6
  • 4
  • 2
12 Comments
 
LVL 17

Expert Comment

by:inthedark
ID: 10781863
Is it like an INI file, is there a keyword that you can search for?
0
 
LVL 17

Expert Comment

by:inthedark
ID: 10781887
It could be like this (I will post the source code for the functions later, if there is a need).

sFileName = "......\machine.config"

' read data from file
sData = GF.ReadFile(sFileName)

' get the bit to the left of the keyword
sLeft = GF.LeftPart(sData, vbcrlf + "Trust =")

' create line to be inserted
sInsert = "NewField = Something"

' stich it all back together
sData = sLeft + vbcrlf + sInsert + vbcrlf + Mid(sData, len(sLleft)+2)

' save data
OK = GF.WriteFile(sFileName, sData)
0
 
LVL 17

Accepted Solution

by:
zzzzzooc earned 75 total points
ID: 10781892
Something like this *should* work..


Form1:
===========

Private Sub Form_Load()
    If AddLine("c:\test.txt", "trust = medium", "my new line") = True Then
        MsgBox "Line added."
    End If
End Sub
Private Function AddLine(ByVal sFile As String, sAfterLine As String, sNewLine As String) As Boolean
    Dim sBuff As String, sLines() As String, iFF As Integer
    Dim iLoop1 As Integer, iLoop2 As Integer
    Dim bFound As Boolean, bDone As Boolean
    'If file exists..
    If Dir(sFile, vbNormal + vbHidden) <> vbNullString Then
        iFF = FreeFile
        Open sFile For Binary As iFF
            sBuff = Space(LOF(iFF))
            Get #iFF, 1, sBuff
        Close iFF
        iFF = FreeFile
        Open sFile For Output As iFF
            sLines = Split(sBuff, vbCrLf)
            For iLoop1 = 0 To UBound(sLines)
                If sAfterLine = sLines(iLoop1) Then
                    bFound = True
                    For iLoop2 = 0 To UBound(sLines)
                        If iLoop1 >= iLoop2 Or bDone = True Then
                            Print #iFF, sLines(iLoop2)
                        Else
                            Print #iFF, sNewLine
                            iLoop2 = iLoop2 - 1
                            bDone = True
                        End If
                    Next iLoop2
                End If
            Next iLoop1
            If bFound = False Then Print #iFF, sNewLine
            AddLine = True
        Close iFF
    End If
End Function
0
 
LVL 17

Expert Comment

by:inthedark
ID: 10781916
Or the old way:

Open sFileName For Input As #1
Open "temp.tmp" For Output as #2

Dim lc as long
Dim L$
Do While Not Eof(1)
    lc= lc + 1 ' line count
    Line Input #1, L$
    If Left(L$, 5)="Trust" Then ' or say If lc = 123 Then
        Print #2, "NewField = Something" ' insrt a new line
        bReplace = False ' is this replace or insert? set = True if replace
    End If
    If Not bReplace Then
        Print #2, L$ ' save the current line
    End If
Loop
Close 1
Close 2
0
 

Author Comment

by:options_technology
ID: 10781921
Windows says the file type is a:

Web Configuration file

The file extension is .config

The keyword that could be searched for to determine which place to add the line after is:

<securityPolicy>

Thanks

Dan

0
 
LVL 17

Expert Comment

by:inthedark
ID: 10781928
Change above as follows, in order to allow insert a line or change a line:

Dim L$
dim bReplace As Boolean ' forgot this
Do While Not Eof(1)
    bReplace = False ' and this
    lc= lc + 1 ' line count
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 17

Expert Comment

by:inthedark
ID: 10781948
As at the end:

Close 1
Close 2
If Len(Dir("Machine.bak")) Then
    Kill "machine.bak"
End If
' don;t do these lines until sure its working ok

Name sFileName As "machine.bak" ' create a backup
Name "temp.tmp" as sFileName ' replace the original file
0
 

Author Comment

by:options_technology
ID: 10782073
Thanks loads for the help so far.

Does anyone know the way to do this on a number of machines on a network?

eg.

for n=0; n < 86; n++ {

    find file machine.config on machine BHWn

    change file on BHWn

}

This is the bit that would really speed up a number of changes on our network.

Thanks

Dan
0
 

Author Comment

by:options_technology
ID: 10782173
Also the location of the file changes from PC to PC.

Would it be possible to use a VB file search API, for example from:

http://www.dutchthewiz.com/vb/files/

and then when searching for the file use something like:

for n=0; n < 86; n++ {

    searchdrive =  "\\bhw" + n + "\C$"

    filelocation = searchfunction("machine.config",searchdrive)

    if filelocation <> null then
        run file changing code
    end if
}

This is only a guess, my apologies if it is a totally stupid idea.

Thanks

Dan
0
 
LVL 17

Expert Comment

by:zzzzzooc
ID: 10782220
So you basically want to enumerate through all computers on the network and then enumerate through all their files remotely and then modify one if it's found..? Should have chosen a different topic title since that'd be the difficult part.

If the files aren't on a similar mapped drive nor in a similar shared folder.. I'm not sure how to possibly go about all of that using windows' file operations.

Going to sleep anyways.. :)~
0
 
LVL 17

Assisted Solution

by:inthedark
inthedark earned 75 total points
ID: 10789944
The simplest way to do this is to call an exe form your system login script.

The exe should decide if a  change has been made since the last run as it may not need to run.

I use a class for file operations, here is an example:


Private Sub Form_Load()

Dim FOP As New zFOP ' my file operations class
Dim Drives As Collection
Dim Drive
Dim sPath As String

Set Drives = FOP.GetDrives ' get a list of local hard drives

' loop through each drive
For Each Drive In Drives
    sPath = FOP.LocateFile("machine.config", Drive + ":\")
    If Len(sPath) > 0 Then
         ' change the file as needed
         ProcessFile sPath
    End If
Next

End Sub


------An extract from class zFOP.cls

Private Declare Function SearchTreeForFile Lib "ImageHlp.dll" (ByVal lpRoot As String, ByVal lpInPath As String, ByVal lpOutPath As String) As Long
Private Declare Function GetDriveType  Lib "kernel32" Alias "GetDriveTypeA" _
              (ByVal nDrive As String) As Long

Public Enum DriveTypes
    DRIVE_UNDETERMINED = 0
    DRIVE_NO_ROOT = 1
    DRIVE_REMOVABLE = 2
    DRIVE_FIXED = 3
    DRIVE_REMOTE = 4
    DRIVE_CDROM = 5
    DRIVE_RAMDISK = 6
End Enum

Function GetDrives(Optional DriveType As DriveTypes = DRIVE_FIXED) As Collection

' Returns a collection of local hard drives
' you can change the optional call as follows:

' Dim Drives As Collection
'Set Drives = GetDrives(DriveTypes.DRIVE_CDROM)
'Set Drives = GetDrives() ' default returns local hard disks

Dim col As Collection
Dim lc As Long
Dim lt As Long
Dim sDrive As String

Set col = New Collection

For lc = 1 To 26
    sDrive = Chr(64 + lc)
    lt = GetDriveType(sDrive + ":\")
    If lt = DriveType Then
        col.Add sDrive
    End If
Next
Set GetDrives = col
   
End Function

Function LocateFile(ByVal strFilename As String, ByVal strRootPath As String) As String

' Code from Ark:
' http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_20270763.html?query=search+for+files+inthedark&searchType=all

'======Input ============
'strFileName - File Name to search
'strRootPath - Path to begin search from. May be drive name
'=====OutPut=============
'Full path to file if success, empty string otherwithe
'Note: return first file matched


' Example:
'Private Sub Command1_Click()
'   Dim sPath As String
'   sPath = LocateFile("excell.exe","c:\")
'   If sPath = "" Then
'      MsgBox "File not found!", vbExlamation
'   Else
'      MsgBox "File full path = " & sPath , vbInformation
'   End if
'End Sub


    Dim strBuffer As String
    Dim lngResult As Long
    Const MAX_PATH = 260
    LocateFile = ""
    strBuffer = String$(MAX_PATH, 0)
    lngResult = SearchTreeForFile(strRootPath, strFilename, strBuffer)
    If lngResult <> 0 Then
        If InStr(strBuffer, vbNullChar) > 0 Then
            LocateFile = Left$(strBuffer, InStr(strBuffer, vbNullChar) - 1)
        End If
    End If
End Function

0
 

Author Comment

by:options_technology
ID: 10811944
Thanks for the help inthedark, thats a great bit of code that will be of help in the future.

The change that we are trying to make to machine.config is a one off change, therefore calling an .exe from a system login would be a waste of resources unless we needed to check for a change every login, also the users do not log in on a regular basis, therefore using this method would result in the change taking a long time to be completed across all the machines.

I am assumning that there is no way to search HD`s and edit files of many machines on the network from ONE pc on the network (otherwise virus writers would have a field day). If this is the case can someone confirm, and I will award the points to inthedark.

Thanks

Dan

0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now