How to write GUID to .ini file using vbscript? - windows

How to write GUID to .ini file using vbscript?
guid = CreateGUID()
WriteIni "testsection", "ID", guid, "H:\test123.ini"
Function CreateGUID()
CreateGUID = ""
Set objTypeLib = CreateObject("Scriptlet.TypeLib")
Wscript.Echo "GUID: " & objTypeLib.Guid
CreateGUID = objTypeLib.Guid
End Function
The above code is not working properly it appends some other character to the GUID of .ini file. For example:
After writing GUID to test123.ini:
[testsection]
ID=EAE11CC4-F60E-4B21-8AA8-E0CE2ADE5521 5
Here extra character(ex: 5 ) was added. It has to update the file like this:
[testsection]
ID=EAE11CC4-F60E-4B21-8AA8-E0CE2ADE5521

It's a known bug in the Scriptlet.TypeLib object. The Guid property should be 38 characters long, but comes back with a length of 40 with 2 garbage characters at the end. You need to trim the Guid value to avoid the issue:
Function CreateGUID()
CreateGUID = ""
Set objTypeLib = CreateObject("Scriptlet.TypeLib")
CreateGUID = Left(TypeLib.Guid, 38) ' With curly braces: {47BC69BD-06A5-4617-B730-B644DBCD40A9}
' CreateGUID = Mid(TypeLib.Guid, 2, 36) ' Without curly braces: 47BC69BD-06A5-4617-B730-B644DBCD40A9
End Function

You're making this more complicated than it needs to be. I'd suggest to read the INI file into a dictionary of dictionaries, so that a file like this:
[Section1]
value1="foo"
value2="bar"
[Section2]
valueX="baz"
becomes a data structure like this:
+-Section1
| +-value1 -> "foo"
| `-value2 -> "bar"
`-Section2
`-valueX -> "baz"
Then you can simply add a GUID to a given section like this:
section = "Section1"
If Not ini.Exists(section) Then
ini.Add section, CreateObject("Scripting.Dictionary")
End If
ini(section)("ID") = CreateObject("Scriptlet.TypeLib").GUID
and write the data back to a file like this:
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile("C:\path\to\your.ini", 2)
For Each section In ini.Keys
f.WriteLine "[" & section & "]"
For Each value In ini(section).Keys
f.WriteLine value & "=" & Chr(34) & ini(section)(value) & Chr(34)
Next
f.WriteLine
Next
f.Close
A while back I wrote a procedure (ParseIni) for parsing INI files into such data structures.

Related

Error on line 63, that I cannot seem to debug.

This is line 63 for me: Set ipAddrFile = fso.OpenTextFile(fileName,Read,ASCII)
I was also getting an error for line 51, but adding the quotes solved my problem.. Well, It got rid of the error. I tried to do the same thing with line 63, but I get the error no matter what. I am also running this program on windows 10 and on a Windows Vista virtual computer.
And this is the Script I'm trying to debug:
' VBScript: IP_FileWrite.vbs
' Written by: Kathleen Williams
' Date: 2/7/18
' Class: COMP230
' Professor: Professor James Lewis
' ===================================
' This initializes a 2-dimension array
' of IP Address. The first index +100
' is the room# and the second index+1
' is the computer# in the room.
dim ipAddress(5,3)
ipAddress(0,0)="192.168.10.11"
ipAddress(0,1)="192.168.10.12"
ipAddress(0,2)="192.168.10.13"
ipAddress(0,3)="192.168.10.14"
ipAddress(1,0)="192.168.10.19"
ipAddress(1,1)="192.168.10.20"
ipAddress(1,2)="192.168.10.21"
ipAddress(1,3)="192.168.10.22"
ipAddress(2,0)="192.168.10.27"
ipAddress(2,1)="192.168.10.28"
ipAddress(2,2)="192.168.10.29"
ipAddress(2,3)="192.168.10.30"
ipAddress(3,0)="192.168.10.35"
ipAddress(3,1)="192.168.10.36"
ipAddress(3,2)="192.168.10.37"
ipAddress(3,3)="192.168.10.38"
ipAddress(4,0)="192.168.10.43"
ipAddress(4,1)="192.168.10.44"
ipAddress(4,2)="192.168.10.45"
ipAddress(4,3)="192.168.10.46"
ipAddress(5,0)="192.168.10.51"
ipAddress(5,1)="192.168.10.52"
ipAddress(5,2)="192.168.10.53"
ipAddress(5,3)="192.168.10.54"
' Define constants, variables and set object properties
CONST ForReading = 1
CONST ForWriting = 2
CONST ForAppending = 8
Const ASCII = 0
'Defining the Variables
fileName = "C:\VBScripts\IP_Addresses.csv"
ipAddrStr = ""
' Create New Folder
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(fileName) Then
fso.DeleteFile(fileName)
End If
Set ipAddrFile = fso.CreateTextFile("fileName,ForWriting,ASCII")
' Read from array and write a line of text.
For room = 0 to 5
For computer = 0 to 3
ipAddrStr = CStr(room+100) & "," & CStr(computer+1) & "," & _
ipAddress(room,computer) & vbCrLf
ipAddrFile.Write(ipAddrStr)
Next
Next
ipAddrFile.close
' Set object properties and close file object.
Set ipAddrFile = fso.OpenTextFile(fileName,Read,ASCII)
WScript.Echo iPAddrFile.ReadAll
ipAddrFile.close
VBScript was designed by at least two people. A genius, who defined the properly named functions CreateTextFile() and OpenTextFile() and
their default arguments to make standard tasks - create an ASCII file, read from an ASCII file - easy:
Option Explicit
Const csFSpec = "48798232.txt"
Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject")
Dim sD : sD = "could be an array, but is just a string for show: " & Now()
' using *Create*TextFile + defaults to always create an ASCII File
Dim tsW : Set tsW = oFS.CreateTextFile(csFSPEC)
tsW.WriteLine sD
tsW.Close
' using OpenTextile + defaults to read from an ASCII File
' no need for a variable or .Close
WScript.Echo oFS.OpenTextFile(csFSPEC).ReadAll()
output:
cscript 48798232.vbs
could be an array, but is just a string for show: 15.02.2018 04:45:06
Then there came the idiot in residence and messed up OpenTextFile() with lots of optional parameters in arbitrary order to make it useable for file creation. From then on people mixed up those functions and their parameter lists.
Code 1: Set ipAddrFile = fso.CreateTextFile("fileName,ForWriting,ASCII")
Create: object.CreateTextFile(filename[, overwrite[, unicode]])
Open: object.OpenTextFile(filename[, iomode[, create[, format]]])
Code 2: Set ipAddrFile = fso.OpenTextFile(fileName,Read,ASCII)
Never being sure of the arguments, their data types, or their order, they use desperate means like quoting the (wrong) argument list.
So: Check the docs carefully (e.g. be aware of the difference between a boolean ForWriting vs. a numerical iomode of the same name (<-- the idiot at work, obviously) and use the defaults for simple/standard tasks.

WSCRIPT error: subscript out of range

I have a VBScript which tries to merge data from two CSV files based upon common field. When I am running my script, then I get an error on Line 5 char 1:
Subscript out of range.
The two files which I am trying to merge based upon the value of a common field between the two are in the same folder where script is also placed.
My code is :
'Instatiate FSO.
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Open the CSV file for reading. The file is in the same folder as the script and named csv_sample.csv.
Wscript.Echo "Path " & objFSO.GetParentFolderName(WScript.ScriptFullName)
'Open the store locations file first
Set brandCSV = objFSO.OpenTextFile(objFSO.GetParentFolderName(WScript.ScriptFullName) & "\" & "SizeGuideLookup_test.csv",1,False)
'Set header status to account for the first line as the column headers.
IsHeader = True
'Initialize the var for the output string.
OutRecord = ""
'Read each line of the file.
Wscript.Echo "Starting Brand File loop"
Do Until brandCSV.AtEndOfStream
brandLine = brandCSV.ReadLine
If IsHeader Then
OutTxt = "PIM Size Type,PIM Identifier,Structure Group,PIM Size Groupd Value Lookup,Size Group To Upload" & vbCrLf
IsHeader = False
Else
'parse brandrecord and get brand id
brandLineArray=Split(brandLine,";")
brandBrandId = brandLineArray(0)
' loop through Store Location file and get matching data
foundLocation=false
Set storeLocCSV = objFSO.OpenTextFile(objFSO.GetParentFolderName(WScript.ScriptFullName) & "\" & "SizeGuideMapping.csv",1,False)
Do Until storeLocCSV.AtEndOfStream
outLine=""
storeLine=storeLocCSV.ReadLine
storeLineArray=Split(storeLine,";")
storeBrandId = storeLineArray(0)
'if the brand IDs match, append the brand data to the end of the store data.
If brandBrandId = storeBrandId Then
' match found - ouptut data (specific fields from store Line + brand line)
outLine = outLine & brandLineArray(0)
outLine = outLine & "," & brandLineArray(1)
outLine = outLine & "," & brandLineArray(2)
outLine = outLine & "," & storeLineArray(1)
outLine = outLine & "," & storeLineArray(1)
foundLocation=true
'append created line to end of output text data
OutTxt = OutTxt & outLine & vbCrLf
End If
Loop
'Close the store location file.
storeLocCSV.close
'if we havent found the data, add empty fields to end of line
if foundLocation=false Then
' no locations for this brand - create brand-only record
outLine = brandLineArray(0) & ",,,"
outLine = outLine & "," & brandLineArray(1)
outLine = outLine & "," & brandLineArray(2)
outLine = outLine & "," & storeLineArray(1)
outLine = outLine & "," & storeLineArray(1)
'append created line to end of output text data
OutTxt = OutTxt & outLine & vbCrLf
end if
End If
Loop
'Close the brand file.
brandCSV.Close
'Open the output file for writing.
Set objOutCSV = objFSO.CreateTextFile(objFSO.GetParentFolderName(WScript.ScriptFullName) & "\" & "brandfile.csv",True)
'Write the var OutTxt to the file overwriting existing contents.
objOutCSV.Write OutTxt
'Close the file.
objOutCSV.Close
Set objFSO = Nothing
The line the error occurs on doesn't tally with the source you have provided (guessing that's not all of it) but it's likely the
WScript.Arguments(0)
causing the Subscript out of range error as the script is expecting an argument (WshUnnamed or WshNamed objects) being passed but there doesn't appear to be one at index 0 in the WshArguments collection object.
If the argument is indeed a file path, then you want to be calling it with either wscript.exe or cscript.exe something like this (at a Command Prompt);
cscript.exe /nologo "yourscript.vbs" "C:\some\file\path"
Then when
WScript.Echo "Path " & WScript.Arguments(0)
is called you should get (based off this example)
C:\some\file\path
Useful Links
Arguments Property (WScript Object)
WshArguments Object
If i am right, you want to get the folder path of the executing script.
For this purpose, you don't want to use WScript.Arguments(0) but FSO.GetParentFolderName(WScript.ScriptFullName).

Populate GPO from Text File using VBScript or other

Ok, so we need to create a GPO that allows our users to only use specific programs.
GPO Location:
User Configuration
Policies
Administrative Templates [...]
System
Run only specified Windows applications
Then setting the GPO to enabled and clicking on List of allowed applications --> Show...
I have created an excel spreadsheet containing the names of all the programs and their associated executable files with other pertinent information so that we can easily organize, add, delete, etc. the executable files that we need to allow our users access to.
This spreadsheet then dumps all the executable files into a text file.
Here is an example of what the text file looks like:
Acrobat.exe
chrome.exe
calc.exe
.
.
.
There are a lot of entries and these are likely subject to change. What I am trying to do is create a script that will take that text file and populate the GPO automatically. I don't care if we have to open the window and then run it, it does not need to run from the task scheduler (although that would be amazing if someone has that code ready). We just need it to populate this ridiculous amount of executable filenames into the fields.
Here is code I found (VBScript) that when run, should populate the fields automatically, however I cannot get it to run in the Group Policy Management Editor (it runs in the windows explorer window instead and ends up searching for some of the files)
' Open the text file, located in the same path as the script
Set objFSO = CreateObject("Scripting.FileSystemObject")
strPath = Mid(Wscript.ScriptFullName, 1, InStrRev(Wscript.ScriptFullName, wscript.ScriptName) -1)
Set objFile = objFSO.OpenTextFile(strPath & "appList.txt")
' Activate the "Show Contents" window with the "List of allowed applications".
' Note the window must be opened already and we should have selected where in
' the list we want to enter the data before running the script
set WshShell = WScript.CreateObject("WScript.Shell")
WScript.Sleep 1000
WshShell.AppActivate "Show Contents"
' Read the file line by line
Do While objFile.AtEndOfStream <> True
' Each line contains one EXE name
exeName = objFile.ReadLine
' Escape forbidden chars { } [ ] ( ) + ^ % ~
exeName = Replace(exeName, "[", "{[}")
exeName = Replace(exeName, "]", "{]}")
exeName = Replace(exeName, "(", "{(}")
exeName = Replace(exeName, ")", "{)}")
exeName = Replace(exeName, "+", "{+}")
exeName = Replace(exeName, "^", "{^}")
exeName = Replace(exeName, "%", "{%}")
exeName = Replace(exeName, "~", "{~}")
' Send the EXE name to the window
WScript.Sleep 100
WshShell.SendKeys exeName
' Move to the next one
WshShell.SendKeys "{TAB}"
Loop
objFile.Close
from: http://blogs.msdn.com/b/alejacma/archive/2011/03/24/how-to-update-quot-run-only-specified-windows-applications-quot-gpo-programmatically-vbscript.aspx
"C:\Windows\System32\GroupPolicy\User\Registry.pol"
Is where my policies are stored. It's a semi text file. Try writing to that file.
Ok, so I tried it many different ways. If anyone is looking for an answer to do this, this is the way I've figured it out and the way I've decided to proceed. I will post all relevant code below.
In Excel, the format of my table is as follows:
(With obviously WAY more entries)
Here is the VBA code I used to turn the data from this file into the proper format for the registry key:
VBA - In Excel
Public Sub ExportToTextFile(FName As String, _
Sep As String, SelectionOnly As Boolean, _
AppendData As Boolean)
Dim WholeLine As String
Dim FNum As Integer
Dim RowNdx As Long
Dim ColNdx As Integer
Dim StartRow As Long
Dim EndRow As Long
Dim StartCol As Integer
Dim EndCol As Integer
Dim CellValue As String
Application.ScreenUpdating = False
On Error GoTo EndMacro:
FNum = FreeFile
StartRow = 2
If SelectionOnly = True Then
With Selection
StartCol = .Cells(2).Column
EndRow = .Cells(.Cells.Count).Row
EndCol = .Cells(2).Column
End With
Else
With ActiveSheet.UsedRange
StartCol = .Cells(2).Column
EndRow = .Cells(.Cells.Count).Row
EndCol = .Cells(2).Column
End With
End If
If AppendData = True Then
Open FName For Append Access Write As #FNum
Else
Open FName For Output Access Write As #FNum
End If
For RowNdx = StartRow To EndRow
WholeLine = ""
For ColNdx = StartCol To EndCol
If Cells(RowNdx, ColNdx).Value = "" Then
CellValue = ""
Else
CellValue = Cells(RowNdx, ColNdx).Value
End If
WholeLine = WholeLine & Chr(34) & CellValue & ".exe" & Chr(34) & "=" & Chr(34) & CellValue & ".exe" & Chr(34) & Sep
Next ColNdx
WholeLine = Left(WholeLine, Len(WholeLine) - Len(Sep))
Print #FNum, WholeLine; ""
Next RowNdx
EndMacro:
On Error GoTo 0
Application.ScreenUpdating = True
Close #FNum
End Sub
Sub PipeExport()
Dim FileName As Variant
Dim Sep As String
FileName = Application.GetSaveAsFilename(InitialFileName:="appList", filefilter:="Text (*.txt),*.txt")
If FileName = False Then
''''''''''''''''''''''''''
' user cancelled, get out
''''''''''''''''''''''''''
Exit Sub
End If
Sep = "|"
If Sep = vbNullString Then
''''''''''''''''''''''''''
' user cancelled, get out
''''''''''''''''''''''''''
Exit Sub
End If
Debug.Print "FileName: " & FileName, "Extension: " & Sep
ExportToTextFile FName:=CStr(FileName), Sep:=CStr(Sep), _
SelectionOnly:=False, AppendData:=False
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
PipeExport
End Sub
The file that is created is appList.txt and its format is the same format as the registry key:
"Acrobat.exe"="Acrobat.exe"
"AcroRd32.exe"="AcroRd32.exe"
Now in your GPO, add a unique program name to the allowed applications list (say test1234.exe) and in your registry editor, go to Edit > Find test1234.exe.
Export that registry key under File > Export. Remove the test1234.exe line and paste in your text file. Then reimport that file and you're done!

VBscript to export total row count to another csv with the ability to add a custom name

I am using the following VBscript to get the total row count from my csv files. I need help in exporting the returned line count to a csv which will have two columns Name and Count name will be anything and the count is the returned count.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
myFile = objArgs(0)
Set objFile = objFSO.OpenTextFile(myFile,1)
Do Until objFile.AtEndOfLine
line = objFile.Line
objFile.ReadLine
Loop
WScript.Echo "Line count of", myFile , "is", line
The way i would like to call the script would be:
Cscript 'vbscript_name' file_name_to_count 'custom_name' 'export_count.csv'
Thanks
Maybe I not see where is the break, as you only need to create new file and write just 2 lines in, but it w'd be something like this:
Set objFile = objFSO.OpenTextFile(objArgs(2), 2, True)
objFile.WriteLine "Name,Count"
objFile.WriteLine objArgs(1) & "," & line
objFile.Close
And just to become more friendly, here is the whole deal:
Set objArgs = WScript.Arguments
iLinesCount = FileLinesCount(objArgs(0))
DumpResult objArgs(2), objArgs(1), iLinesCount
WScript.Echo "File: " & objArgs(0) & " has " & iLinesCount & " lines"
Function FileLinesCount(strFileName)
With CreateObject("Scripting.FileSystemObject")
With .OpenTextFile(strFileName, 1)
Do Until .AtEndOfStream
Call .ReadLine
Loop
FileLinesCount = .Line
End With
End With
End Function
Sub DumpResult(strFileName, strCustomName, iCount)
With CreateObject("Scripting.FileSystemObject")
With .OpenTextFile(strFileName, 2, True)
.WriteLine "Name,Count"
.WriteLine strCustomName & "," & iCount
End With
End With
End Sub
Also it's good to add error checks for your command line arguments, but I live this simple task to you, cheers!
P.S. I suppose you'll prefer to append your count data to existing file instead of creating new file for each counted source file. If so, you have a very little work on DumpResult function, just need to open the file for appending (ForAppending = 8) and add "header" (column names) only then needs (i.e. when the file is newly created):
' modified version w`d be:
Sub DumpResult(strFileName, strCustomName, iCount)
With CreateObject("Scripting.FileSystemObject")
With .OpenTextFile(strFileName, 8, True)
If .Line = 1 Then ' new empty file
.WriteLine "Name,Count" ' add column names
End If
.WriteLine strCustomName & "," & iCount
End With
End With
End Sub

Vbscript - Read ini or text file for specific section

I want to store some addresses in a text file and then read specific portions of the file, based on group membership. I've done all of the group membership stuff so I don't need any help for that.
But I'm not sure if I should use a plain text file or an INI file?
The thing is, the post addresses are in two or three lines and I need line break.
I tried using a plain text file, but I couldn't manage to get a line break correctly.
So INI files would be preferable?
The INI file could look like this:
[London]
Address 1
Postbox 3245
58348 London
[Copenhagen]
Address 2
Postbox 2455
5478347 Copenhagen
I'm not quite sure if this is possible in an INI file though, perhaps I need to name each line as well. OR, I could possibly use a plain text file and search for the word [london] and then read each line until there's a line break. Then store all of those lines in a variable that I'll pass along?
How would you guys solve this?
I have written a small VBScript Class that handles "real' ini files written with such format:
[section_name]
key1 = value1
key2 = value2
The code for the class is:
Class IniFileObject
Private m_Data
Private Sub Class_Initialize
Set m_Data = Server.CreateObject("Scripting.Dictionary")
End Sub
Private Sub Class_Terminate
Dim key
If IsObject(m_Data) Then
For Each key In m_Data
m_Data(key).RemoveAll
Set m_Data(key) = Nothing
Next
m_Data.RemoveAll
Set m_Data = Nothing
End If
End Sub
Public Function Init(sFilePath)
Dim arrLines, sLine, x
Dim sCurSection, oSectionDict
Set Init = Me
arrLines = GetFileLines(sFilePath)
If Not(IsArray(arrLines)) Then Exit Function
sCurSection = ""
For x = 0 To UBound(arrLines)
sLine = Trim(arrLines(x))
If Len(sLine)>0 Then
If Left(sLine, 1)="[" Then
If Not(HandleSectionLine(sLine, sCurSection)) Then Exit Function
Else
If Len(sCurSection)=0 Then
Err.Raise 1005, "IniFileObject init", "Found value outside any section (" & Server.HTMLEncode(sLine) & ")"
Exit Function
End If
Set oSectionDict = m_Data(sCurSection)
If Not(ParseOneLine(sLine, oSectionDict)) Then Exit Function
Set m_Data(sCurSection) = oSectionDict
End If
End If
Next
End Function
Public Property Get ReadValue(section, key)
Dim oSectionDict
ReadValue = ""
If m_Data.Exists(section) Then
Set oSectionDict = m_Data(section)
If oSectionDict.Exists(key) Then ReadValue = oSectionDict(key)
End If
End Property
Private Function ParseOneLine(ByVal sLine, ByRef oSectionDict)
Dim arrTemp, sErrorMsg, sKey
sErrorMsg = ""
ParseOneLine = True
If Left(sLine, 2)="//" Or Left(sLine, 1)="'" Or Left(sLine, 1)="{" Then Exit Function
arrTemp = Split(sLine, "=")
If UBound(arrTemp)=1 Then
sKey = Trim(arrTemp(0))
If (Len(sKey)>0) And (Len(arrTemp(1))>0) Then
If Not(oSectionDict.Exists(sKey)) Then
oSectionDict.Add sKey, Trim(arrTemp(1))
Else
sErrorMsg = "Key already exists"
End If
Else
sErrorMsg = "Empty key or value"
End If
Else
sErrorMsg = "Missing or too much '=' characters"
End If
Erase arrTemp
If Len(sErrorMsg)>0 Then
ParseOneLine = False
Err.Raise 1006, "IniFileObject Init", "Failed to parse single line (" & Server.HTMLEncode(sLine) & "): " & sErrorMsg
End If
End Function
Private Function HandleSectionLine(ByVal sLine, ByRef sCurSection)
HandleSectionLine = False
If (Len(sLine)<3) Or (Right(sLine, 1)<>"]") Then
Err.Raise 1002, "IniFileObject init", "Invalid line found: " & Server.HTMLEncode(sLine)
Exit Function
End If
sCurSection = Mid(sLine, 2, Len(sLine) - 2)
If m_Data.Exists(sCurSection) Then
Err.Raise 1003, "IniFileObject init", "Section exists more than once: " & Server.HTMLEncode(sCurSection)
Exit Function
End If
m_Data.Add sCurSection, Server.CreateObject("Scripting.Dictionary")
HandleSectionLine = True
End Function
Private Function GetFileLines(sFilePath)
Dim objFSO, oFile
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
If Not(objFSO.FileExists(sFilePath)) Then
Set objFSO = Nothing
Err.Raise 1001, "IniFileObject init", "file path '" & Server.HTMLEncode(sFilePath) & "' does not exist, check permissions"
Exit Function
End If
Set oFile = objFSO.OpenTextFile(sFilePath)
GetFileLines = Split(oFile.ReadAll, VBCrLf)
oFile.Close
Set oFile = Nothing
Set objFSO = Nothing
End Function
End Class
Usage example:
Dim filePath, ini
filePath = Server.MapPath("config.ini")
Set ini = New IniFileObject.Init(filePath)
Response.Write("Value for 'Key001': " & ini.ReadValue("MySection", "Key001") & "<br />")
Set ini = Nothing
The code throw various errors when the file does not exist or contains invalid lines, the errors are pretty much clear. It's possible to "suppress" the errors and not display error page by using such code when consuming:
On Error Resume Next
Set ini = New IniFileObject.Init(filePath)
If Err.Number<>0 Then
Response.Write("Error reading ini file")
End If
On Error Goto 0
If IsObject(ini) Then
Response.Write("Value for 'IP001': " & ini.ReadValue("IPaddress", "IP001") & "<br />")
Set ini = Nothing
End If
I would probably use CSV file instead where each row will represent a country.
Country,Address1,Address2,Address3,Address4
London,Address 1,Postbox 3245,58348 London
Copenhagen,Address 2,Postbox 2455,5478347,Copenhagen
If you can easily identify your data then you could probably have more descriptive column names (i.e. Street1, Street2, Town, Postcode, etc.).
This file format is also easy to read since you only read one line of the input file at a time and split it using something like
aAddress = split(sLine, ",")
To make it even easier to work with you could use dictionary object and use country as a key and array as a value
'sLine should be read from input file'
sLine = "Copenhagen,Address 2,Postbox 2455,5478347,Copenhagen"
'Create dictionary for addresses'
Set dic = CreateObject("Scripting.Dictionary")
'Split line into array'
aAddressParts = Split(sLine, ",")
'Remove the first element of the array'
sValues = Mid(sLine, InStr(sLine, ",")+1)
aValues = Split(sValues, ",")
'Add new entry into dictionary'
dic.Add aAddressParts(0), aValues
'Usage'
MsgBox "Address for Copenhagen: " & vbNewLine & _
Join(dic("Copenhagen"), "," & vbNewLine)
Thanks,
Maciej
You could store the addresses in one line and use a special character, for example an underscore, to indicate a line break. When you read the address, you just need to replace the special character with a line break.
[London]
Address = "Postbox 3245_58348
London"
[Copenhagen]
Address = "Postbox
2455_5478347 Copenhagen"
That allows you to store addresses with more lines or without a postbox line, as well. In my experience, information like "our addresses always have exactly two lines and the first one is always a postbox" is very often incorrect...
I use a small executable that launches native api for that: GetPrivateProfileString and WritePrivateProfileString.
The executable is called like that:
Set sh = CreateObject("WScript.Shell")
Set exec = sh.Exec("ini.exe get %APPDATA%\sth\file.ini ""Section name"" key")
sFirma1 = exec.StdOut.ReadLine
Call sh.Run("ini.exe set %APPDATA%\sth\file.ini ""Section name"" key set_value", 0)
See also Running command line silently with VbScript and getting output?.
This is the code of the executable:
#include <stdio.h>
#include <windows.h>
void usage()
{
puts("ini <get>/<set> <file> <section> <key> <value>");
exit(1);
}
int main(int cArg, char **aszArg)
{
int iFile = 2;
int iSection = 3;
int iKey = 4;
int iValue = 5;
if (cArg < 5) usage();
if (strcmp(aszArg[1], "get") != 0 && strcmp(aszArg[1], "set") != 0) usage();
if (strcmp(aszArg[1], "set") == 0 && cArg < iValue + 1) usage();
if (strcmp(aszArg[1], "set") == 0) {
if (!WritePrivateProfileString(aszArg[iSection], aszArg[iKey],
aszArg[iValue], aszArg[iFile]))
puts("Failure in WriteProfileString.");
} else {
char buf[1000];
buf[0] = 0;
GetPrivateProfileString(
aszArg[iSection], aszArg[iKey], "", buf, 999, aszArg[iFile]);
puts(buf);
}
return 0;
}
You need to compile it using a c compiler for Windows. I did it with gcc, but a free compiler from ms should also work. If this page with a 32-bit executable is still available, you may give it a try, but on your own responsibility. Hackers already visited my site once.

Resources