' ***********************************************************************
' Assembly : Reg2Bat
' Author : Elektro
' Modified : 01-28-2014
' ***********************************************************************
' <copyright file="Reg2Bat.vb" company="Elektro Studios">
' Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************
#Region " Usage Examples "
' Dim BatchScript As String = Reg2Bat.Convert("C:\RegistryFile.reg")
' IO.File.WriteAllText("Converted.bat", Reg2Bat.Convert("C:\RegistryFile.reg"), System.Text.Encoding.Default)
#End Region
#Region " Imports "
Imports System.ComponentModel
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions
#End Region
''' <summary>
''' Converts a Registry Script to a Batch Script.
''' </summary>
Public Class Reg2Bat
#Region " ReadOnly Strings "
''' <summary>
''' Indicates the resulting Batch-Script Header.
''' </summary>
Private Shared ReadOnly BatchHeader As String =
<a>:: Converted with Reg2Bat by Elektro
@Echo OFF
</a>.Value
''' <summary>
''' Indicates the resulting Batch-Script Footer.
''' </summary>
Private Shared ReadOnly BatchFooter As String =
<a>
Pause&Exit</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a Comment-Line command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_Comment As String =
<a>REM {0}</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a REG Key-Add command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_KeyAdd As String =
<a>REG ADD "{0}" /F</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a REG Key-Delete command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_KeyDelete As String =
<a>REG DELETE "{0}" /F</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a REG DefaultValue-Add command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_DefaultValueAdd As String =
<a>REG ADD "{0}" /V "" /D {1} /F</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a REG Value-Add REG_SZ command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_ValueAdd_REGSZ As String =
<a>REG ADD "{0}" /V "{1}" /T "REG_SZ" /D "{2}" /F</a>.Value
''' <summary>
''' Indicates the Batch command StringFormat of a REG Value-Add BINARY command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_ValueAdd_BINARY As String =
<a>REG ADD "{0}" /V "{1}" /T "REG_BINARY" /D "{2}" /F</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a REG Value-Add DWORD command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_ValueAdd_DWORD As String =
<a>REG ADD "{0}" /V "{1}" /T "REG_DWORD" /D "{2}" /F</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a REG Value-Add QWORD command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_ValueAdd_QWORD As String =
<a>REG ADD "{0}" /V "{1}" /T "REG_QWORD" /D "{2}" /F</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a REG Value-Add EXPAND_SZ command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_ValueAdd_EXPANDSZ As String =
<a>REG ADD "{0}" /V "{1}" /T "REG_EXPAND_SZ" /D "{2}" /F</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a REG Value-Add MULTI_SZ command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_ValueAdd_MULTISZ As String =
<a>REG ADD "{0}" /V "{1}" /T "REG_MULTI_SZ" /D "{2}" /F</a>.Value
''' <summary>
''' Indicates the Batch syntax StringFormat of a REG Value-Delete command.
''' </summary>
Private Shared ReadOnly BatchStringFormat_ValueDelete As String =
<a>REG DELETE "{0}" /V "{1}" /F</a>.Value
''' <summary>
''' Indicates the string to split a BINARY registry line.
''' </summary>
Private Shared ReadOnly RegistryValueSplitter_BINARY As String =
<a>=HEX</a>.Value
''' <summary>
''' Indicates the string to split a DWORD registry line.
''' </summary>
Private Shared ReadOnly RegistryValueSplitter_DWORD As String =
<a>=DWORD:</a>.Value
''' <summary>
''' Indicates the string to split a QWORD registry line.
''' </summary>
Private Shared ReadOnly RegistryValueSplitter_QWORD As String =
<a>=HEX\(b\):</a>.Value
''' <summary>
''' Indicates the string to split a EXPAND_SZ registry line.
''' </summary>
Private Shared ReadOnly RegistryValueSplitter_EXPANDSZ As String =
<a>=HEX\(2\):</a>.Value
''' <summary>
''' Indicates the string to split a MULTI_SZ registry line.
''' </summary>
Private Shared ReadOnly RegistryValueSplitter_MULTISZ As String =
<a>=HEX\(7\):</a>.Value
''' <summary>
''' Indicates the string to split a REG_SZ registry line.
''' </summary>
Private Shared ReadOnly RegistryValueSplitter_REGSZ As String =
<a>"="</a>.Value
#End Region
#Region " Enumerations "
''' <summary>
''' Indicates the data type of a registry value.
''' </summary>
Public Enum RegistryValueType As Integer
''' <summary>
''' A null-terminated string.
''' This will be either a Unicode or an ANSI string.
''' </summary>
REG_SZ = 0
''' <summary>
''' Binary data.
''' </summary>
BINARY = 1
''' <summary>
''' A 32-bit number.
''' </summary>
DWORD = 2
''' <summary>
''' A 64-bit number.
''' </summary>
QWORD = 3
''' <summary>
''' A null-terminated string that contains unexpanded references to environment variables
''' (for example, "%WinDir%").
''' </summary>
EXPAND_SZ = 4
''' <summary>
''' A sequence of null-terminated strings, terminated by an empty string (\0).
'''
''' The following is an example:
''' String1\0String2\0String3\0LastString\0\0
''' The first \0 terminates the first string,
''' the second to the last \0 terminates the last string,
''' and the final \0 terminates the sequence.
''' Note that the final terminator must be factored into the length of the string.
''' </summary>
MULTI_SZ = 5
End Enum
#End Region
#Region " Public Methods "
''' <summary>
''' Converts a Registry Script to a Batch Script.
''' </summary>
''' <param name="RegistryFile">Indicates the registry file to convert.</param>
''' <returns>System.String.</returns>
Public Shared Function Convert(ByVal RegistryFile As String) As String
' Split the Registry content.
Dim RegistryContent As String() =
String.
Join("@@@Reg2Bat@@@",
File.
ReadAllLines(RegistryFile
)).
Replace("\@@@Reg2Bat@@@ ", Nothing).
Replace("@@@Reg2Bat@@@", Environment.NewLine).
Split(Environment.NewLine)
' Where the registry line to convert will be stored.
Dim RegLine As String = String.Empty
' Where the registry key to convert will be stored.
Dim RegKey As String = String.Empty
' Where the registry value to convert will be stored.
Dim RegVal As String = String.Empty
' Where the registry data to convert will be stored.
Dim RegData As String = String.Empty
' Where the decoded registry strings will be stored.
Dim BatchCommands As New StringBuilder
' Writes the specified Batch-Script Header.
BatchCommands.AppendLine(BatchHeader)
' Start reading the Registry File.
For X As Long = 0 To RegistryContent.LongLength - 1
RegLine = RegistryContent(X).Trim
Select Case True
Case RegLine.StartsWith(";"), RegLine.StartsWith("#") ' It's a comment line.
BatchCommands.AppendLine(
String.Format(BatchStringFormat_Comment, RegLine.Substring(1, RegLine.Length - 1).Trim))
Case RegLine.StartsWith("[-") ' It's a key to delete.
RegKey = RegLine.Substring(2, RegLine.Length - 3).Trim
BatchCommands.AppendLine(String.Format(BatchStringFormat_KeyDelete, RegKey))
Case RegLine.StartsWith("[") ' It's a key to add.
RegKey = RegLine.Substring(1, RegLine.Length - 2).Trim
BatchCommands.AppendLine(String.Format(BatchStringFormat_KeyAdd, RegKey))
Case RegLine.StartsWith("@=") ' It's a default value to add.
RegData = RegLine.Split("@=").Last
BatchCommands.AppendLine(String.Format(BatchStringFormat_DefaultValueAdd, RegKey, RegData))
Case RegLine.StartsWith("""") _
AndAlso RegLine.Split("=").Last = "-" ' It's a value to delete.
RegVal = RegLine.Substring(1, RegLine.Length - 4)
BatchCommands.AppendLine(String.Format(BatchStringFormat_ValueDelete, RegKey, RegVal))
Case RegLine.StartsWith("""") ' It's a value to add.
Select Case RegLine.Split("=")(1).Split(":").First.ToUpper
Case "HEX" ' It's a Binary value.
RegVal = FormatRegistryString(GetRegistryValue(RegLine, RegistryValueType.BINARY))
RegData = GetRegistryData(RegLine, RegistryValueType.BINARY)
BatchCommands.AppendLine(
String.Format(BatchStringFormat_ValueAdd_BINARY, RegKey, RegVal, RegData))
Case "DWORD" ' It's a DWORD value.
RegVal = FormatRegistryString(GetRegistryValue(RegLine, RegistryValueType.DWORD))
RegData = GetRegistryData(RegLine, RegistryValueType.DWORD)
BatchCommands.AppendLine(
String.Format(BatchStringFormat_ValueAdd_DWORD, RegKey, RegVal, RegData))
Case "HEX(B)" ' It's a QWORD value.
RegVal = FormatRegistryString(GetRegistryValue(RegLine, RegistryValueType.QWORD))
RegData = GetRegistryData(RegLine, RegistryValueType.QWORD)
BatchCommands.AppendLine(
String.Format(BatchStringFormat_ValueAdd_QWORD, RegKey, RegVal, RegData))
Case "HEX(2)" ' It's a EXPAND_SZ value.
RegVal = FormatRegistryString(GetRegistryValue(RegLine, RegistryValueType.EXPAND_SZ))
RegData = FormatRegistryString(GetRegistryData(RegLine, RegistryValueType.EXPAND_SZ))
BatchCommands.AppendLine(
String.Format(BatchStringFormat_ValueAdd_EXPANDSZ, RegKey, RegVal, RegData))
Case "HEX(7)" ' It's a MULTI_SZ value.
RegVal = FormatRegistryString(GetRegistryValue(RegLine, RegistryValueType.MULTI_SZ))
RegData = FormatRegistryString(GetRegistryData(RegLine, RegistryValueType.MULTI_SZ))
BatchCommands.AppendLine(
String.Format(BatchStringFormat_ValueAdd_MULTISZ, RegKey, RegVal, RegData))
Case Else ' It's a REG_SZ value.
RegVal = FormatRegistryString(GetRegistryValue(RegLine, RegistryValueType.REG_SZ))
RegData = FormatRegistryString(GetRegistryData(RegLine, RegistryValueType.REG_SZ))
BatchCommands.AppendLine(
String.Format(BatchStringFormat_ValueAdd_REGSZ, RegKey, RegVal, RegData))
End Select ' RegLine.Split("=")(1).Split(":").First.ToUpper
End Select ' RegLine.StartsWith("""")
Next X ' RegLine
' Writes the specified Batch-Script Footer.
BatchCommands.AppendLine(BatchFooter)
Return BatchCommands.ToString
End Function
#End Region
#Region " Private Methods "
''' <summary>
''' Gets the registry value of a registry line.
''' </summary>
''' <param name="RegistryLine">Indicates the registry line.</param>
''' <param name="RegistryValueType">Indicates the type of the registry value.</param>
''' <returns>System.String.</returns>
Private Shared Function GetRegistryValue(ByVal RegistryLine As String,
ByVal RegistryValueType As RegistryValueType) As String
Dim Value As String = String.Empty
Select Case RegistryValueType
Case RegistryValueType.BINARY
Value = Regex.Split(RegistryLine,
RegistryValueSplitter_BINARY,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).First()
Case RegistryValueType.DWORD
Value = Regex.Split(RegistryLine,
RegistryValueSplitter_DWORD,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).First()
Case RegistryValueType.QWORD
Value = Regex.Split(RegistryLine,
RegistryValueSplitter_QWORD,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).First()
Case RegistryValueType.EXPAND_SZ
Value = Regex.Split(RegistryLine,
RegistryValueSplitter_EXPANDSZ,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).First()
Case RegistryValueType.MULTI_SZ
Value = Regex.Split(RegistryLine,
RegistryValueSplitter_MULTISZ,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).First()
Case RegistryValueType.REG_SZ
Value = Regex.Split(RegistryLine,
RegistryValueSplitter_REGSZ,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).First()
End Select
If Value.StartsWith("""") Then
Value = Value.Substring(1, Value.Length - 1)
End If
If Value.EndsWith("""") Then
Value = Value.Substring(0, Value.Length - 1)
End If
Return Value
End Function
''' <summary>
''' Gets the registry data of a registry line.
''' </summary>
''' <param name="RegistryLine">Indicates the registry line.</param>
''' <param name="RegistryValueType">Indicates the type of the registry value.</param>
''' <returns>System.String.</returns>
Private Shared Function GetRegistryData(ByVal RegistryLine As String,
ByVal RegistryValueType As RegistryValueType) As String
Dim Data As String = String.Empty
Select Case RegistryValueType
Case RegistryValueType.BINARY
Data = Regex.Split(RegistryLine,
Regex.Split(RegistryLine,
RegistryValueSplitter_BINARY, RegexOptions.IgnoreCase Or RegexOptions.Singleline).First &
RegistryValueSplitter_BINARY,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).
Last.
Replace(",", Nothing)
Case RegistryValueType.DWORD
Data = Regex.Split(RegistryLine,
Regex.Split(RegistryLine,
RegistryValueSplitter_DWORD, RegexOptions.IgnoreCase Or RegexOptions.Singleline).First &
RegistryValueSplitter_DWORD,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).
Last.
Replace(",", Nothing)
Data = "0x" & Data
Case RegistryValueType.QWORD
RegistryLine =
String.Join(Nothing,
Regex.Split(RegistryLine,
Regex.Split(RegistryLine,
RegistryValueSplitter_QWORD, RegexOptions.IgnoreCase Or RegexOptions.Singleline).First &
RegistryValueSplitter_QWORD,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).
Last.
Reverse)
For Each [Byte] As String In RegistryLine.Split(",")
Data &= String.Join(Nothing, [Byte].Reverse)
Next [Byte]
Data = "0x" & Data
Case RegistryValueType.EXPAND_SZ
RegistryLine = Regex.Split(RegistryLine,
Regex.Split(RegistryLine,
RegistryValueSplitter_EXPANDSZ, RegexOptions.IgnoreCase Or RegexOptions.Singleline).First &
RegistryValueSplitter_EXPANDSZ,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).
Last.
Replace(",00", "").
Replace("00,", "")
For Each [Byte] As String In RegistryLine.Split(",")
Data &= Chr(Val("&H" & [Byte]))
Next [Byte]
Data = Data.Replace("""", "\""")
Case RegistryValueType.MULTI_SZ
RegistryLine = Regex.Split(RegistryLine,
Regex.Split(RegistryLine,
RegistryValueSplitter_MULTISZ, RegexOptions.IgnoreCase Or RegexOptions.Singleline).First &
RegistryValueSplitter_MULTISZ,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).
Last.
Replace(",00,00,00", ",\0").
Replace(",00", "").
Replace("00,", "")
For Each [Byte] In RegistryLine.Split(",")
If [Byte] = "\0" Then
Data &= "\0" ' Multiline separator.
Else
Data &= Chr(Val("&H" & [Byte]))
End If
Next
Return Data.Replace("""", "\""")
Case RegistryValueType.REG_SZ
Data = Regex.Split(RegistryLine,
Regex.Split(RegistryLine,
RegistryValueSplitter_REGSZ, RegexOptions.IgnoreCase Or RegexOptions.Singleline).First &
RegistryValueSplitter_REGSZ,
RegexOptions.IgnoreCase Or RegexOptions.Singleline).
Last
Data = Data.Substring(0, Data.Length - 1).Replace("\\", "\")
End Select
Return Data
End Function
''' <summary>
''' Properly formats a registry string to insert it in a Batch command string.
''' </summary>
''' <param name="RegistryString">Indicates the Reg Batch command string.</param>
''' <returns>System.String.</returns>
Private Shared Function FormatRegistryString(ByVal RegistryString As String) As String
RegistryString = RegistryString.Replace("%", "%%")
If Not RegistryString.Contains("""") Then
Return RegistryString
End If
RegistryString = RegistryString.Replace("\""", """")
Dim strArray() As String = RegistryString.Split("""")
For X As Long = 1 To strArray.Length - 1 Step 2
strArray(X) = strArray(X).Replace("^", "^^") ' This replacement need to be THE FIRST.
strArray(X) = strArray(X).Replace("<", "^<")
strArray(X) = strArray(X).Replace(">", "^>")
strArray(X) = strArray(X).Replace("|", "^|")
strArray(X) = strArray(X).Replace("&", "^&")
' strArray(X) = strArray(X).Replace("\", "\\")
Next X
Return String.Join("\""", strArray)
End Function
#End Region
#Region " Hidden methods "
' These methods are purposely hidden from Intellisense just to look better without unneeded methods.
' NOTE: The methods can be re-enabled at any-time if needed.
<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Sub Equals()
End Sub
<EditorBrowsable(EditorBrowsableState.Never)>
Public Shadows Sub ReferenceEquals()
End Sub
#End Region
End Class