Reading keys in a .reg file and output to .csv

I have this snippet that does the following

1. Opens a .reg file
2. Scans for strings after the "DisplayName" and DisplayVersion" headers
 
For every instance of "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" the script should loop and find the two headers before proceeding to the next instance of "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"

3. Outputs the file to .csv

Problem here is that the script appears to be reading the input .reg file but nothing appears in the .csv file. I'm also wondering if the script compensates for instances where DisplayVersion is not available for a given application

 I've included the .vbs and .reg file for testing

set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile("ST-PI.reg")
set objOutput = objFSO.CreateTextFile("ST-PI.csv")

Do while not objFile.AtEndOfStream
        strCurrentLine = objFile.ReadLine
        
        If Instr(strCurrentLine,"DisplayName") then
                strName = Replace(Split(strCurrentLine,"=")(1),chr(34),"")
        End if
        If Instr(strCurrentLine,"DisplayVersion") then
                strVersion = Replace(Split(strCurrentLine,"=")(1),chr(34),"")
                objOutput.WriteLine strName &";" &strVersion
        End if
Loop

Open in new window

ST-PI.reg
NanohurtzChromeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

zorvek (Kevin Jones)ConsultantCommented:
You are opening the file in ASCII mode when the file is a double byte file. Use this code:

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("ST-PI.reg.txt", 1, , -1)
Set objOutput = objFSO.CreateTextFile("ST-PI.csv")

Do While Not objFile.AtEndOfStream
        strCurrentLine = objFile.ReadLine
       
        If InStr(strCurrentLine, "DisplayName") Then
                strName = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
        End If
        If InStr(strCurrentLine, "DisplayVersion") Then
                strVersion = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
                objOutput.WriteLine strName & ";" & strVersion
        End If
Loop

Kevin
0
merowingerCommented:
Hey :)
the script seems to work, but there's a problem with the original reg file. If you copy the whole content and create a new .reg file with this content it works.
I'm wondering what's the problem with the original reg file.

If i output the current line on the original file i get some strange values, you can also try it with the following command in line 7
wscript.echo strCurrentLine
0
NanohurtzChromeAuthor Commented:
Hey Zorvek,

The code works nicely, only 2 minor things.

1. Must I rename the .reg file to .reg.txt everytime I use the snippet
2. The output to .CSV looks like this:

PI MCN Health Monitor Client SMT 3.2.x Plug-Ins;3.4.375.38
PI Rampsoak ICU Control (Rampsoak);3.2.0.0
PI ProcessBook 3.2.0.0;1.2.4.0
PI OPC HDA/DA Server;1.4.1.0
PI SNMP (pisnmp) Interface (full version);6.9.3.113
Debugging Tools for Windows (x86);8.28.13.0
HP Array Configuration Utility;3.4.380.36
PI Totalizer Subsystem;2.1.10.800
HP Version Control Repository Manager;1.6.2.0
PI Ping (piping) Interface (full version);9.3.4035.00
Microsoft SQL Server 2005 Tools Express Edition;1.2.10.0
PI GenericNames DLL;9.3.4035.00
Microsoft SQL Server 2005 Express Edition;1.4.0.0
PI Performance Monitor (piperfmon) ICU Control;11.0.5002.333
Symantec Endpoint Protection;2.1.0.0
PI Diagnostics Manager;3.4.380.36

It's not outputting each "DisplayName" and "DisplayVersion" into it's own columns.


0
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

zorvek (Kevin Jones)ConsultantCommented:
>Must I rename the .reg file to .reg.txt everytime I use the snippet

No. You can name the file anything you want with any extension.

>It's not outputting each "DisplayName" and "DisplayVersion" into it's own columns.

I replaced the semicolon with a tab:

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("ST-PI.reg.txt", 1, , -1)
Set objOutput = objFSO.CreateTextFile("ST-PI.csv")

Do While Not objFile.AtEndOfStream
        strCurrentLine = objFile.ReadLine
       
        If InStr(strCurrentLine, "DisplayName") Then
                strName = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
        End If
        If InStr(strCurrentLine, "DisplayVersion") Then
                strVersion = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
                objOutput.WriteLine strName & vbTab & strVersion
        End If
Loop

Kevin
0
NanohurtzChromeAuthor Commented:
Zorvek,

The output is as expected with the comma delimination, but there's an error with the output file.

The DisplayName does not correspond with the correct DisplayVersion. It's as if they are severly skewed.

Did you incorporate logic in the event  "DisplayVersion" is not detected under each corresponding header (""HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall {someID}") for the corresponding "DisplayName"?

These following versions are not correct

HP Array Configuration Utility      3.4.380.36 (this version is from another application)
PI Totalizer Subsystem      2.1.10.800  (this version is from another application)
HP Version Control Repository Manager      1.6.2.0  (this version is from another application)
PI Ping (piping) Interface (full version)      9.3.4035.00  (this version is from another application)

The logic I'm thinking is something like this

Use Case

"For every instance of "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall {someID}" Capture DisplayName and corresponding "DisplayVersion". Print to file.
If a DisplayVersion is NOT available for the corresponding DisplayName, print DisplayVersion as "no version found" or ""(blank).

Example: Scenario where code is successful

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Adobe Flash Player ActiveX]
"DisplayName"="Adobe Flash Player 10 ActiveX"
"DisplayVersion"="10.0.12.36"
"Publisher"="Adobe Systems Incorporated"
"URLInfoAbout"="http://www.adobe.com/go/getflashplayer"
"VersionMajor"="10"

Example: Scenario where the code is "tricked" or produces an erred output

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\KB925398_WMP64]
"DisplayName"="Security Update for Windows Media Player 6.4 (KB925398)"
"UninstallString"="\"C:\\WINDOWS\\$NtUninstallKB925398_WMP64$\\spuninst\\spuninst.exe\""
"TSAware"=dword:00000001
"NoModify"=dword:00000001
"InstallDate"="20081105"
"Publisher"="Microsoft Corporation"
"NoRepair"=dword:00000001
"HelpLink"="http://support.microsoft.com/?kbid=925398"
"URLInfoAbout"="http://support.microsoft.com"
"RegistryLocation"="HKLM\\SOFTWARE\\Microsoft\\Updates\\Windows Media Player 6.4\\KB925398_WMP64"
"ReleaseType"="Security Update"
"DisplayIcon"=hex(2):22,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,\
  00,69,00,6c,00,65,00,73,00,25,00,5c,00,77,00,69,00,6e,00,64,00,6f,00,77,00,\
  73,00,20,00,6d,00,65,00,64,00,69,00,61,00,20,00,70,00,6c,00,61,00,79,00,65,\
  00,72,00,5c,00,6d,00,70,00,6c,00,61,00,79,00,65,00,72,00,32,00,2e,00,65,00,\
  78,00,65,00,22,00,00,00
"ParentKeyName"="OperatingSystem"

There is no "DisplayVersion". I think this is where the code started to skew things. Thanks plenty for your huge help.


0
zorvek (Kevin Jones)ConsultantCommented:
Try this:

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("ST-PI.reg.txt", 1, , -1)
Set objOutput = objFSO.CreateTextFile("ST-PI.csv")

Do While Not objFile.AtEndOfStream
        strCurrentLine = objFile.ReadLine
        If InStr(strCurrentLine, "DisplayName") Then
                strName = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
        End If
        If InStr(strCurrentLine, "DisplayVersion") Then
                strVersion = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
        End If
        If InStr(strCurrentLine, "HKEY_LOCAL_MACHINE") Then
                objOutput.WriteLine strName & vbTab & strVersion
                strName = ""
                strVersion = ""
        End If
Loop

Kevin
0
merowingerCommented:
could you please try this one:
counter = 0
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("ST-PI.reg", 1, , -1)
Set objOutput = objFSO.CreateTextFile("ST-PI.csv")

Do While Not objFile.AtEndOfStream
        strCurrentLine = objFile.ReadLine
       
        If InStr(strCurrentLine, "DisplayName") Then
                strName = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
		counter = counter + 1
        End If
        If InStr(strCurrentLine, "DisplayVersion") Then
                strVersion = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
		counter = counter + 1
        End If

	If counter = 2 Then
                objOutput.WriteLine strName & vbTab & strVersion
		counter = 0
	End If
Loop

Open in new window

0
NanohurtzChromeAuthor Commented:
Zorvek,

Excellent! I sampled 15 of the apps and they correspond with the correct version now.

The only tiny concern is that when I open it in excel - the DisplayName is joined to the DisplayVersion with an unknown (delimeter) character. I'm sure it's a simple fix.. see attached image.

Fantastic work - I'm excited!
unknownchar.jpg
0
zorvek (Kevin Jones)ConsultantCommented:
That unknown character is a tab. Let's go back to semicolon:

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("ST-PI.reg.txt", 1, , -1)
Set objOutput = objFSO.CreateTextFile("ST-PI.csv")

Do While Not objFile.AtEndOfStream
        strCurrentLine = objFile.ReadLine
        If InStr(strCurrentLine, "DisplayName") Then
                strName = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
        End If
        If InStr(strCurrentLine, "DisplayVersion") Then
                strVersion = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
        End If
        If InStr(strCurrentLine, "HKEY_LOCAL_MACHINE") Then
                objOutput.WriteLine strName & ";" & strVersion
                strName = ""
                strVersion = ""
        End If
Loop

Kevin
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
NanohurtzChromeAuthor Commented:
Zorvek,

I'm speechless. You have just spared me several days of work. Many thanks friend. I'm going to close this and accept your solution.

One last annoying request, and it's completely optional at this point for all you have done.

Can you add a routine to eliminate the blanks between records?
removeblank.jpg
0
NanohurtzChromeAuthor Commented:
A credit to his title. Many, many thanks!
0
zorvek (Kevin Jones)ConsultantCommented:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("ST-PI.reg.txt", 1, , -1)
Set objOutput = objFSO.CreateTextFile("ST-PI.csv")

Do While Not objFile.AtEndOfStream
        strCurrentLine = objFile.ReadLine
        If InStr(strCurrentLine, "DisplayName") Then
                strName = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
        End If
        If InStr(strCurrentLine, "DisplayVersion") Then
                strVersion = Replace(Split(strCurrentLine, "=")(1), Chr(34), "")
        End If
        If InStr(strCurrentLine, "HKEY_LOCAL_MACHINE") And (strName <> "" Or strVersion <> "") Then
                objOutput.WriteLine strName & ";" & strVersion
                strName = ""
                strVersion = ""
        End If
Loop

Kevin
0
NanohurtzChromeAuthor Commented:
/cheers
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.