Board logo

标题: REG2BAT.VBS 注册表文件转换脚本 [打印本页]

作者: slore     时间: 2009-12-1 07:40    标题: REG2BAT.VBS 注册表文件转换脚本

'------------------------------------------------------------------------------
'名称:Reg2Bat.VBS
'功能:REG文件转换为BAT、CMD文件。
'     REG命令功能有限,仅支持常用类型。
'      (REG_SZ、REG_DWORD、REG_BINARY、
'         REG_EXPAND_SZ、REG_MULTI_SZ)
'
'                                   By Slore
'                             更新于:2009-12-06
'
'如果对脚本有任何意见和建议,可发送相关信息至:
'                              slorelee@yahoo.com.cn
'
'声明:
'本人支持开源,代码未作任何加密,可自由转载,但请
'尊重他人劳动成果,转载请务必注明出处和原作者。
'------------------------------------------------------------------------------

'---------------------------
'Reg2Bat By Slore
'---------------------------
'命令行参数说明(不区分大小写)
'/?、/h、/help  查看此帮助信息
'/i:RegFileName 指定要转换的注册表文件路径
'/o:BatFileName 指定转换后的批处理文件路径
'可选参数
'/S:Separator   REG_MULTI_SZ 数据字符串中用作分隔符的字符
'               仅限一个字符,默认"\0"用作分隔符
'/Q             安静模式,不弹出错误提示
'/NF            转换后REG命令无/F参数
'/NH            忽略注册表文件头检测
'
'例如:
'简易模式:CScript Reg2Bat.vbs [/i:]slore.reg /S:轩 /Q
'         省略批处理文件路径,将输出为注册表文件同名文件。
'经典模式:CScript Reg2Bat.vbs slore.reg slore.bat /S:轩 /Q
'         其中注册表文件路径和批处理文件路径顺序不可调换。
'标准模式:CScript Reg2Bat.vbs /i:slore.reg /o:slore.bat /S:轩 /Q
'         其中/i:、/o:、/S:中的冒号不可省略,顺序可变。
'---------------------------

Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const blnOverWrite = True

Const
adTypeBinary = 1
Const adModeReadWrite = 3

Const ANSI = 0
Const Unicode = - 1

Const REG_SEPARATOR = "\0"       '默认分隔符

Const BatHead = "@echo off"      '转换后的批处理文件头
Const DefaultBatFileExt = "bat"  '默认批处理文件扩展名


Dim RegHexType(10)
RegHexType(0) = "REG_NONE":RegHexType(1) = "REG_SZ"
RegHexType(2) = "REG_EXPAND_SZ":RegHexType(3) = "REG_BINARY"
RegHexType(4) = "REG_DWORD":RegHexType(5) = "REG_DWORD_BIG_ENDIAN"
RegHexType(6) = "REG_LINK":RegHexType(7) = "REG_MULTI_SZ"
RegHexType(8) = "REG_RESOURCE_LIST":RegHexType(9) = "REG_FULL_RESOURCE_DESCRIPTOR"

Dim RegSeptr

Dim blnForce,blnSilent,IgnoreRegHead
blnForce = True            '强制修改数据
blnSilent = False          '不显示提示信息
IgnoreRegHead = False      '忽略注册表文件头检测

Dim RegFile,BatFile

Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")

'参数处理
With WSH.Arguments
    If .Count <> 0 Then
        If .
Named.Exists("?") Then ShowHelp
        If .Named.Exists("h") Then ShowHelp
        If .Named.Exists("help") Then ShowHelp
        If .Named.Exists("i") Then RegFile = .Named.Item("i")
        
If .Named.Exists("o") Then BatFile = .Named.Item("o")
        
If .Named.Exists("s") Then RegSeptr = .Named.Item("s")
        
If .Named.Exists("q") Then blnSilent = True
        If .
Named.Exists("nf") Then blnForce = False
        If .
Named.Exists("nh") Then IgnoreRegHead = True
        If .
Unnamed.Count > 0 Then
            
RegFile = .Unnamed.Item(0)
            
If Not objFSO.FileExists(RegFile) Then WSH.Quit
            If .Unnamed.Count > 1 Then
               
BatFile = .Unnamed.Item(1)
            
Else
               
BatFile = Left(RegFile,InstrRev(RegFile,".")) & DefaultBatFileExt
            End If
        End If
    End If
End With

If Len
(RegSeptr) = 0 Then
   
RegSeptr = REG_SEPARATOR
Else
   
RegSeptr = Left(RegSeptr,1)
End If

'选择注册表文件
If RegFile = "" Then
   
RegFile = OpenFile(".","注册表文件(*.reg)|*.reg")
   
If RegFile = "" Then WSH.Quit
Else
   
BatFile = Left(RegFile,InstrRev(RegFile,".")) & DefaultBatFileExt
End If
If Not
objFSO.FileExists(RegFile) Then WSH.Quit
'选择批处理文件
If BatFile = "" Then BatFile = OpenFile(".","批处理文件(*.bat,*.cmd)|*.bat;*.cmd")
If BatFile = "" Then WSH.Quit

Dim objRegFile
Set objRegFile = objFSO.GetFile(RegFile)
If objRegFile.Size < 2 Then
    If Not
blnSilent Then MsgBox "选择的注册表文件无内容。",vbInformation,"文件无效"
        WSH.Quit
End If
'获取注册表文件编码
Dim FileEncoding
FileEncoding = GetEncoding(RegFile)
If FileEncoding = "ANSI" Then
   
OpenFormat = ANSI
ElseIf FileEncoding = "Unicode" Then
   
OpenFormat = Unicode
Else
    If Not
blnSilent Then MsgBox "注册表文件的编码不正确。",vbInformation,"文件编码:" & FileEncoding
    WSH.Quit
End If

'格式化注册表文件
Dim RegStr,RegLine
Set objFile = objFSO.OpenTextFile(RegFile,ForReading,False,OpenFormat)
Do Until objFile.AtEndOfStream
    RegLine = MyTrim(objFile.ReadLine)
   
If RegLine <> "" Then '清除空行
        'If Left(RegLine,1) <> ";" Then RegStr = RegStr & RegLine & vbCrLf '清除注释行
        
RegStr = RegStr & RegLine & vbCrLf
    End If
Loop
objFile.Close

'合并hex(?)类型多行数据
Dim hStr,hPos,RegChar
hPos = InStr(1,RegStr,",\" & vbCrLf)
Do While hPos > 0
    RegChar = Mid(RegStr,hPos + 4,1)
   
If InStr(1,"[@""",RegChar) > 0 Then
        
RegStr = Left(RegStr,hPos - 1) & Mid(RegStr,hPos + 2)
   
ElseIf RegChar = ";" Then
        
RemEnd = InStr(hPos + 5,RegStr,vbCrLf)
        
If RemEnd = 0 Then
            
RegStr = Left(RegStr,hPos - 1)
        
Else
            
RegStr = Left(RegStr,hPos) & Mid(RegStr,RemEnd + 2)
        
End If
    Else
        
RegStr = Left(RegStr,hPos) & Mid(RegStr,hPos + 4)
   
End If
   
hPos = InStr(hPos + 4,RegStr,",\" & vbCrLf)
Loop

'替换主键为缩写
RegStr = Replace(RegStr,vbCrLf & "[HKEY_LOCAL_MACHINE\",vbCrLf & "[HKLM\")
RegStr = Replace(RegStr,vbCrLf & "[HKEY_CURRENT_USER\",vbCrLf & "[HKCU\")
RegStr = Replace(RegStr,vbCrLf & "[HKEY_CLASSES_ROOT\",vbCrLf & "[HKCR\")
RegStr = Replace(RegStr,vbCrLf & "[HKEY_USER\",vbCrLf & "[HKU\")
RegStr = Replace(RegStr,vbCrLf & "[HKEY_CUREENT_CONFIG\",vbCrLf & "[HKCC\")

RegStr = Replace(RegStr,vbCrLf & "[-HKEY_LOCAL_MACHINE\",vbCrLf & "[-HKLM\")
RegStr = Replace(RegStr,vbCrLf & "[-HKEY_CURRENT_USER\",vbCrLf & "[-HKCU\")
RegStr = Replace(RegStr,vbCrLf & "[-HKEY_CLASSES_ROOT\",vbCrLf & "[-HKCR\")
RegStr = Replace(RegStr,vbCrLf & "[-HKEY_USER\",vbCrLf & "[-HKU\")
RegStr = Replace(RegStr,vbCrLf & "[-HKEY_CUREENT_CONFIG\",vbCrLf & "[-HKCC\")

'对格式化后的注册表文件进行转换
Dim RegLines,n
RegLines = Split(RegStr,vbCrLf)
n = UBound(RegLines)

If Not IgnoreRegHead Then
'检验文件头
   
If RegLines(0) <> "REGEDIT4" And _
        RegLines(0) <> "Windows Registry Editor Version 5.00" Then
        If Not
blnSilent Then MsgBox "不是合法注册表文件头",vbInformation,"错误"
        WSH.Quit
    End If
End If

Dim
RegCommand,BatStr
Dim i,RegKey,RegVal,RegType,RegData

If blnForce Then sForce = " /f" Else sForce = ""

Dim o '为1是删除,为0是添加
Dim vPos
Dim HeadChar,LastHeadChar
LastHeadChar = ""
For i = 1 To n
    HeadChar = Left(RegLines(i),1)
   
If HeadChar = "[" Then
        If
LastHeadChar = "[" And o = 0 Then '添加项
            
BatStr = BatStr & RegCommand & RegKey & sForce & vbCrLf
        End If
        If Mid
(RegLines(i),2,1) = "-" Then
            
RegCommand = "reg delete "
            o = 1
        Else
            
RegCommand = "reg add "
            o = 0
        End If
        
RegKey = """" & Mid(RegLines(i),2 + o,Len(RegLines(i)) - 2 - o) & """"
        If o = 1 Then '删除项
            
BatStr = BatStr & RegCommand & RegKey & sForce & vbCrLf
            
RegKey = ""
        End If
    ElseIf
HeadChar = "@" And (Not Len(RegKey)) Then
        
RegLines(i) = Replace(RegLines(i),"\\",vbNullChar)
        
RegVal = " /ve "
        GetTD Replace(Mid(RegLines(i),3),vbNullChar,"\"),RegType,RegData
        If RegData = "-" Then
            
BatStr = BatStr & "reg delete " & RegKey & " /ve " & sForce & vbCrLf
        Else
            If
RegType <> "REG_SZ" Then
               
RegType = " /t " & RegType
            Else
               
RegType = ""
            End If
            
BatStr = BatStr & "reg add " & RegKey & " /ve" & RegType & " /d " & RegData & sForce & vbCrLf
        End If
    ElseIf
HeadChar = """" And (Not Len(RegKey)) Then
        
RegLines(i) = Replace(RegLines(i),"\\",vbNullChar)
        
vPos = InStr(2,RegLines(i),"""=")
        
If vPos > 2 Then
            If Mid
(RegLines(i),vPos - 1,1) = "\" Then
                Do Until Mid
(RegLines(i),vPos - 1,1) <> "\"
                    vPos = InStr(vPos + 2,RegLines(i),"""=")
                    
If vPos = 0 Then Exit Do
                Loop
            End If
            If
vPos <> 0 Then
               
RegVal = Replace(Left(RegLines(i),vPos),vbNullChar,"\")
               
RegVal = RegSpe(RegVal,0)
               
GetTD Replace(Mid(RegLines(i),vPos + 2),vbNullChar,"\"),RegType,RegData
                If RegData = "-" Then
                    
BatStr = BatStr & "reg delete " & RegKey & " /v " & RegVal & sForce & vbCrLf
                Else
                    If
RegType <> "REG_SZ" Then
                        
RegType = " /t " & RegType
                    Else
                        
RegType = ""
                    End If
                    
BatStr = BatStr & "reg add " & RegKey & " /v " & RegVal & RegType & " /d " & RegData & sForce & vbCrLf
                End If
            End If
        End If
    ElseIf
HeadChar = ";" Then  '注释内容处理(仅支持纯注释行,并且不在Hex数据中间。)
        
BatStr = BatStr & "rem " & Mid(RegLines(i),2) & vbCrLf
        
HeadChar = LastHeadChar
    End If
   
LastHeadChar = HeadChar
Next

'保存为批处理文件
If Len(BatHead) Then BatStr = BatHead & vbCrLf & BatStr
If InStr(1,".bat.cmd",LCase(Right(BatFile,4))) = 0 Then BatFile = BatFile & "." & DefaultBatFileExt
Set objFile = objFSO.CreateTextFile(BatFile,blnOverWrite)
objFile.Write BatStr
objFile.Close

Sub
ShowHelp()
   
MsgBox "命令行参数说明(不区分大小写)" & vbCrLf & _
            "/?、/h、/help  查看此帮助信息" & vbCrLf & _
             "/i:RegFileName 指定要转换的注册表文件路径" & vbCrLf & _
              "/o:BatFileName 指定转换后的批处理文件路径" & vbCrLf & _
               "可选参数" & vbCrLf & _
                "/S:Separator   REG_MULTI_SZ 数据字符串中用作分隔符的字符" & vbCrLf & _
                 "               仅限一个字符,默认""\0""用作分隔符" & vbCrLf & _
                  "/Q             安静模式,不弹出错误提示" & vbCrLf & _
                   "/NF            转换后REG命令无/F参数" & vbCrLf & _
                    "/NH            忽略注册表文件头检测" & vbCrLf & vbCrLf & _
                     "例如:" & vbCrLf & _
                      "简易模式:CScript Reg2Bat.vbs [/i:]slore.reg /S:轩 /Q" & vbCrLf & _
                       "         省略批处理文件路径,将输出为注册表文件同名文件" & vbCrLf & _
                        "经典模式:CScript Reg2Bat.vbs slore.reg slore.bat /S:轩 /Q" & vbCrLf & _
                         "         其中注册表文件路径和批处理文件路径顺序不可调换。" & vbCrLf & _
                          "标准模式:CScript Reg2Bat.vbs /i:slore.reg /o:slore.bat /S:轩 /Q" & vbCrLf & _
                           "         其中/i:、/o:、/S:中的冒号不可省略,顺序可变。" _
                            ,vbInformation,"Reg2Bat By Slore"
    WSH.Quit
End Sub

'---------------------------------自定义函数-------------------------------
'打开文件函数
'参数:初始路径,文件类型过滤器
Function OpenFile(IntDir,Fltr)
   
Dim objDialog
    Set objDialog = CreateObject("UserAccounts.CommonDialog")
   
objDialog.Filter = Fltr
    objDialog.InitialDir = IntDir
    intResult = objDialog.ShowOpen
    If intResult Then
        
OpenFile = objDialog.FileName
    Else
        
OpenFile = ""
    End If
End Function

'检测文本文件编码
Function GetEncoding(FileName)
   
Dim objStreamR,HeadBin,HeadBytes(1)
   
Set objStreamR = CreateObject("Adodb.Stream")
   
objStreamR.Type = adTypeBinary
    objStreamR.Mode = adModeReadWrite
    objStreamR.Open
    objStreamR.LoadFromFile FileName
    HeadBin = objStreamR.Read(2)
   
objStreamR.Close
    HeadBytes(0) = AscB(MidB(HeadBin,1,1))
   
HeadBytes(1) = AscB(MidB(HeadBin,2,1))
   
GetEncoding = "ANSI"
    If HeadBytes(0) = &HFF And HeadBytes(1) = &HFE Then GetEncoding = "Unicode"
    If HeadBytes(0) = &HFE And HeadBytes(1) = &HFF Then GetEncoding = "Unicode Big Endian"
    If HeadBytes(0) = &HEF And HeadBytes(1) = &HBB Then GetEncoding = "UTF-8"
End Function

'剔除字符串两边的Tab字符和空格
Function MyTrim(iStr)
   
Dim sPos,ePos
    sPos = 1
    For i = 1 To Len(iStr)
        
If Mid(iStr,i,1) = vbTab or Mid(iStr,i,1) = " " Then
            
sPos = i + 1
        Else
            Exit For
        End If
    Next
   
ePos = Len(iStr)
   
For i = Len(iStr) To 1 Step - 1
        If Mid(iStr,i,1) = vbTab or Mid(iStr,i,1) = " " Then
            
ePos = i - 1
        Else
            Exit For
        End If
    Next
    If
(ePos - sPos + 1) < 0 Then
        
MyTrim = ""
        Exit Function
    End If
   
MyTrim = Mid(iStr,sPos,ePos - sPos + 1)
End Function

Sub
GetTD(iStr,oType,oData)
   
Dim i
    oType = "":oData = ""
    If iStr = "" Then  Exit Sub
    If
iStr = "-" Then oData = "-":Exit Sub
    If Left
(iStr,1) = """" Then
        
oType = "REG_SZ"
        oData = RegSpe(iStr,0)
   
ElseIf LCase(Left(iStr,4)) = "hex:" Then
        
oType = "REG_BINARY"
        oData = """" & Replace(Mid(iStr,5),",","") & """"
    ElseIf LCase(Left(iStr,6)) = "dword:" Then
        
oType = "REG_DWORD"
        oData = Hex2Dec(Mid(iStr,7))
   
Else
        For
i = 0 To 9
            If LCase(Left(iStr,7)) = "hex(" & i & "):" Then
               
oType = RegHexType(i)
               
If (i = 1) or (i = 2) or (i = 3) or (i = 7) Then
                    
oData = RegHexToAscii(Replace(Mid(iStr,8),",",""),i,RegSeptr)
               
Else
                    
oData = """对不起,这是不支持的类型。"""
                End If
                Exit For
            End If
        Next
    End If
End Sub

Function
RegSpe(iStr,t)
   
Dim i,f,QPos
    If Left(iStr,1) = """" Then
        
RegSpe = Mid(iStr,2,Len(iStr) - 2) '去除双引号
   
Else
        
RegSpe = iStr
    End If
   
'反斜杠与引号字符串处理
   
QPos = - 1
    Do Until QPos = 0
        QPos = InstrRev(RegSpe,"\""",QPos)
        
If QPos = 0 Then Exit Do
        
f = t
        For i = QPos To 1 Step - 1
            If Mid(RegSpe,i,1) = "\" Then
                If
f = 1 Then
                    
RegSpe = Left(RegSpe,i) & "\" & Mid(RegSpe,i + 1)
               
Else
                    
f = 1
                End If
            Else
                Exit For
            End If
        Next
        
QPos = i
    Loop
    For
i = Len(RegSpe) To 1 Step - 1
        If Mid(RegSpe,i,1) = "\" Then
            
RegSpe = RegSpe & "\"
        Else
            Exit For
        End If
    Next
   
'百分号字符处理
   
RegSpe = Replace(RegSpe,"%","%%")
   
'对HexData转ASCII的引号字符进行转义
   
If t = 1 Then
        
RegSpe = Replace(RegSpe,"""","\""")
   
End If
   
'添加双引号
   
RegSpe = """" & RegSpe & """"
End Function

Function
Hex2Dec(strHex)
   
Hex2Dec = 268435456 * CLng("&H" & Left(strHex,1))
   
Hex2Dec = Hex2Dec + CLng("&H" & Mid(strHex,2))
End Function

Function
RegHexToAscii(iStr,RegTypeIndex,Separator)
   
Dim i,n,sRet,HexL,HexH
    For i = 1 To Len(iStr) Step 4
        HexL = Mid(iStr, i, 2)
        
HexH = Mid(iStr, i + 2, 2)
        
If HexL & HexH = "0000" Then
            If
RegTypeIndex = 7 Then '多字符串(REG_MULTI_SZ)类型
               
HexChar = Separator
            Else 'ElseIf RegTypeIndex = 2 Then '可扩充字符串(REG_EXPAND_SZ)类型
               
Exit For
            End If
        ElseIf
HexL = "00" Then
            
HexChar = Chr(CLng("&H" & HexL))
        
Else
            
HexChar = ChrW(CLng("&H" & HexH & HexL))
        
End If
        
sRet = sRet & HexChar
    Next
    If
RegTypeIndex = 7 Then
        
n = Len(Separator)
        
Do Until Right(sRet,n) <> Separator
            sRet = Left(sRet,Len(sRet) - n)
        
Loop
    End If
   
RegHexToAscii = RegSpe(sRet,1)
End Function


[ Last edited by slore on 2009-12-7 at 11:24 ]
作者: newxso     时间: 2009-12-1 11:44
效果不错,能与现成的 Reg2Cmd.exe 相比美。但还是有一点点小建议,就是用傻瓜式转换,即把 Reg 文件拖到脚本身上就自动在相应目录转换成相同名称的 Bat文件。

(我现成的会员级数只能加 2 分,希望笑纳)
作者: slore     时间: 2009-12-1 14:23
测试reg2cmd
对\与"共存没有处理好。还有其他类型。。。不该处理它都处理为reg_sz了。




这个少了一段。。。对结尾是\的符号处理。


Function RegSpe(iStr,t)
    Dim i,f,QPos
    If Left(iStr,1) = """" Then
        RegSpe = Mid(iStr,2,Len(iStr) - 2) '去除双引号
    Else
        RegSpe = iStr
    End If
    '反斜杠与引号字符串处理
    QPos = - 1
    Do Until QPos = 0
        QPos = InstrRev(RegSpe,"\""",QPos)
        If QPos = 0 Then Exit Do
        f = t
        For i = QPos To 1 Step - 1
            If Mid(RegSpe,i,1) = "\" Then
                If f = 1 Then
                    RegSpe = Left(RegSpe,i) & "\" & Mid(RegSpe,i + 1)
                Else
                    f = 1
                End If
            Else
                Exit For
            End If
        Next
        QPos = i
    Loop
    For i = Len(RegSpe) To 1 Step - 1
        If Mid(RegSpe,i,1) = "\" Then
            RegSpe = RegSpe & "\"
        Else
            Exit For
        End If
    Next

    '百分号字符处理
    RegSpe = Replace(RegSpe,"%","%%")
    '对HexData转ASCII的引号字符进行转义
    If t = 1 Then
        RegSpe = Replace(RegSpe,"""","\""")
    End If
    '添加双引号
    RegSpe = """" & RegSpe & """"
End Function
作者: slore     时间: 2009-12-1 14:24
这个建议,晚上的回来加上好了。

主要懒得处理要是重名了,是直接覆盖掉?还是另外加_X命名?
作者: slore     时间: 2009-12-1 15:40
更新:
根据newxso的建议,多加了2种模式。
将/F设置为缺省,改为/NF,使调用更方便。
(可以拖上来就直接生成了,默认是覆盖方式
  Const blnOverWrite = True,改False将不覆盖)


修正\"和空格的处理。
作者: aries215     时间: 2009-12-1 18:36    标题: 反馈!

1、......

2、无法处理某些REG_NONE数据:

下面这个附件是我稍加处理的样本,实测 reg2bat.bat 、reg2cmd.exe 、reg2inf.exe 三个工具都不能完美转换:
http://rthost.fam.cx/cndos-up/img/1762.rar

②部分未处理:

原Reg数据:

  Quote:
[HKEY_CURRENT_USER\Software\Classes\RealPlayer.RAX.6\shell\open\command]  @="\"D:\\Program Files\\Real\\RealPlayer\\RealPlay.exe\" \"%1\""

转换后数据不标准,还有“\\”呢:

  Quote:
reg add "HKLM\SOFTWARE\Classes\RealPlayer.RAX.6\shell\open\command" /ve /t REG_SZ /d "\"D:\\Program Files\\Real\\RealPlayer\\RealPlay.exe\" \"%%1\"" /f

正确的批处理路径形式应该是:"\"D:\Program Files\EmEditor\EmEditor.exe\" %%1"


3、界面问题:
我转换RealPlayer的注册表项,360KB,双击VBS选中Reg后,要很久才弹出对话框让我定义Bat文件名。噢~!天呐~~我还以为那时正在转换呢!

[ Last edited by aries215 on 2009-12-9 at 16:34 ]
作者: aries215     时间: 2009-12-1 19:14
我不是很满意reg2cmd.exe,某些数据还是转换得不完美;27/41个安软报毒!

非常期待楼主能完美解决这两个问题,而且VBS能方便看代码,踏实多了。

[ Last edited by aries215 on 2009-12-2 at 09:07 ]
作者: aries215     时间: 2009-12-1 20:02
还有一个建议:
希望在生成的Bat文件开头,自动添加“@echo off” 。
作者: aries215     时间: 2009-12-1 22:23
哎呀~!没仔细看帖,原来支持命令行转换的,呵呵!
那就可以批量转换了~
作者: slore     时间: 2009-12-2 00:09
感谢测试。。。其实对\\处理了,但是代码放到以"开头的,忘了@了。

代码增加1行就可以了。

    ElseIf HeadChar = "@" And (Not Len(RegKey)) Then
        RegLines(i) = Replace(RegLines(i),"\\",vbNullChar)
        RegVal = " /ve "
        GetTD Replace(Mid(RegLines(i),3),vbNullChar,"\"),RegType,RegData
        If RegData = "-" Then
            BatStr = BatStr & "reg delete " & RegKey & " /ve " & sForce & vbCrLf
        Else
            BatStr = BatStr & "reg add " & RegKey & " /ve /t " & RegType & " /d " & RegData & sForce & vbCrLf
        End If
作者: slore     时间: 2009-12-2 00:15
应该是这样。

reg add "HKCU\Software\Classes\RealPlayer.RAX.6\shell\open\command" /ve /t REG_SZ /d "\"D:\Program Files\Real\RealPlayer\RealPlay.exe\" \"%%1\"" /f


/t REG_SZ 这个下次处理,或者自己加下?
至于文件头可以加

'保存为批处理文件
下面加:
BatStr = "@echo off" & vbCrLf & BatStr
作者: slore     时间: 2009-12-2 00:21
ElseIf HeadChar = "@" And (Not Len(RegKey)) Then下面
       BatStr = BatStr & "reg add " & RegKey & " /ve /t " & RegType & " /d " & RegData & sForce & vbCrLf

改为
BatStr = BatStr & "reg add " & RegKey & " /ve  /d " & RegData & sForce & vbCrLf


ElseIf HeadChar = """" And (Not Len(RegKey)) Then
下面


BatStr = BatStr & "reg add " & RegKey & " /v " & RegVal & RegType & " /d " & RegData & sForce & vbCrLf改为
                If RegData = "-" Then
                    BatStr = BatStr & "reg delete " & RegKey & " /v " & RegVal & sForce & vbCrLf
                Else
                    If RegType <> "REG_SZ" Then
                        RegType = " /t " & RegType
                    Else
                        RegType = ""
                    End If
                    BatStr = BatStr & "reg add " & RegKey & " /v " & RegVal & RegType & " /d " & RegData & sForce & vbCrLf
                End If
作者: aries215     时间: 2009-12-2 08:51
楼主真伟大,解决了这些老问题,呵呵~~也非常感谢那么谦虚地接受建议!

试了一下,文件开头有了“@echo off” 了,路径都是“\”而不再有双斜杠了,“/t REG_SZ”被清除掉了,但稍感遗憾的是“/ve  /d”中间共有两个空格,我不会搞。

顺便分享一下我的Converter Handler (我比较喜欢转成CMD格式),如果还能再优化一下代码就更好了:
CODE:  [Copy to clipboard]
@echo off
title Registry Files Converter Handler
setlocal enableextensions
cd %cd%
:start
cls
echo.
echo.
echo.
echo.
echo.
echo.
echo.                        a.Reg2Cmd        b.Reg2Inf
echo.
echo.
echo.
set choice=
set /p choice=                        请输入选项:
if not "%choice%"=="" set choice=%choice:~0,1%
if /i "%choice%"=="A" goto 2cmd
if /i "%choice%"=="B" goto 2inf
goto start
:2cmd
for /f %%i in ('dir /b /a "*.reg"') do (
CScript Reg2Cmd.vbs %%~ni.reg %%~ni.cmd /Q
)
goto end
:2inf
for /f %%i in ('dir /b /a "*.reg"') do (
Reg2Inf "%%~ni.reg" "%%~ni.inf" /longflags /RepVars
)
pause
goto end
:end
exit
[ Last edited by aries215 on 2010-10-8 at 18:38 ]
作者: basdk     时间: 2009-12-2 10:42
好东西!楼主辛苦了!
收藏了,必——必须的。
作者: aries215     时间: 2009-12-2 10:57
“/t REG_SZ”我自己还是保存不清除了。O(∩_∩)O~
作者: slore     时间: 2009-12-2 15:31
保存是因为REG_NONE类型的问题。

reg 命令虽然支持reg_none

但是和binary有区别。binnary可以直接些HEX格式,但是reg_none得用ASCII……

所以REG_NONE的根本处理不了。

FF FF这个能转那个汉字?

我会及时更新,你上面的问题已经解决了。
对不支持的格式输出该格式不支持但是能用。
常规格式应该都没有问题。
作者: slore     时间: 2009-12-2 15:37
已经更新,感谢测试。

继续测试看看还有什么问题。
作者: aries215     时间: 2009-12-2 18:37
哎呀~抱歉,我的键盘上午进水了,干脆彻底清洗了,凉了一个下午,所以刚才都只能看帖不能回帖,真叫做“咫尺天涯”啊。
现在可以了!
作者: aries215     时间: 2009-12-2 19:04
惊讶这种处理结果,数据变成中文了根本无法使用,下面三项好像都错了:

  Quote:
reg add "HKCU\Software\DownloadManager" /v "evQueueStarted" /t REG_NONE /d "对不起,这是不支持的类型。" /f
reg add "HKCU\Software\DownloadManager" /v "windowPlacementV5" /t REG_EXPAND_SZ /d "," /f
reg add "HKCU\Software\DownloadManager" /v "sortOrder" /t REG_DWORD /d 0 /f

我用的是英文原版,它没提供中文版,所以根本不会有汉字,这几个虽是“REG_NONE” 但仍是 hex(0) 头的键值,在注册表里跟其它进制形式还是一样,建议就按普通十六进制数据处理。老实说,我并不懂hex(0) 、hex(2) 、hex(6) 这些技术细节,但是我看到的数据是一样的,在注册表里显示的和导出来后看到的相同,差别只是中间分隔的符号不同,注册表里是空格导出来是逗号。

Reg2Inf.exe 好像就是类似十六进制的方法转换的。

[ Last edited by aries215 on 2009-12-2 at 20:33 ]
作者: aries215     时间: 2009-12-2 19:41
下面这个是Reg2Inf.exe 的转换结果,部分数据也不正确:

  Quote:
[REGEntries.AddReg]
HKCU,"Software\DownloadManager","TipFilePos",0x00010001,a0,00,00,00  HKCU,"Software\DownloadManager","tvfrdt",0x00020001,fb,7b,1f,5e  HKCU,"Software\DownloadManager","evDownloadFailed""=hex(0):44,6f,77,6e,6c,6f,61,64,20,66,61,69,6c,65,64,00,fb,\    92,7c,14,f8,12,00,b0,f6,12,00,1c,f8,12,00,5c,f6,12,00,58,d9,92,7c,bc,fc,12,\    00,18,ee,92,7c,78,fb,92,7c,ff,ff,ff,ff,71,fb,92,7c,81,d5,da,77,1a,00,00,00,\  ""windowPlacementV5",0x00020000,",???????????????????f???"  HKCU,"Software\DownloadManager","sortOrder",0x00010001,00,00,00,00  

我就不明白了,这有什么复杂的呢?REG_NONE和REG_BINARY在注册表里的数字和导出来的是一样的,只是类型的名字不一样而已。

[ Last edited by aries215 on 2009-12-2 at 19:42 ]
作者: aries215     时间: 2009-12-2 20:25
功能方面几点建议:

改进执行策略:
目前是:双击Reg2Bat.vbs 指定*.reg 文件后,脚本已经开始执行了,所以如果目标文件比较大,要过好一阵子,才能弹出对话框让我们定义转换后的路径和文件名。
我觉得,应该把保存的代码放在比较靠前,尽量挨着 “ '选择注册表文件 ”,两个对话框之间不应该处理数据,应该紧接着进行才好。一是搞错了重新再来也不用等,方便用户即时修正;二是长时间没弹出第二个对话框容易让人误会,我刚碰到这情况的时候,以为操作错误又重复了两遍,最后放弃了,过好一会儿,突然弹出一个对话框让我选择保存位置和文件名!

容错性改进:

1、希望保留所有数据。
前面我提供的测试样本最后,有一个注册表键未作任何改动,是:

  Quote:
[HKEY_CURRENT_USER\Software\RealNetworks\RealMediaSDK\6.0\Preferences\PluginHandlerData\PluginInfo1]

此键的数据量庞大,其中有些还用空行隔开,Reg2Bat.vbs 会忽略空行之后的数据的,导致转换结果不完整。而Reg2Inf.exe 能完整保留。虽然这些数据没有什么价值,但希望这个工具完美一些。

也可以考虑把注释内容也添加进去,把原来的注释符号“ ; ” “#” 等换成“ rem ” 就行。

2、Reg2Bat.vbs 是根据文件开头来判断的,个人觉得可以放宽一点,根据有没有注册表键来判断。虽然加一个文件头不是难事,我个人通常是提取其中一部分来转换的,如果判断标准放得宽一点,不用文件头也能转换,就可以给我这种懒人提供一点方便,呵呵!

[ Last edited by aries215 on 2009-12-2 at 22:26 ]
作者: slore     时间: 2009-12-3 07:51
reg add 命令你说怎么写入REG_NONE类型数据值是 FF,FF

reg add /d后面需要用字符串。。。参数,所以才转换不了的,BINARY格式reg命令使用的是直接十六进制格式字符串3100FFFF这样。

纯英文的话。。。比如 1对应ascii 31

hex(0):31,00,00,00
能转为1

如果hex(0):31,00,00,00,ff,ff,00,00,32,00
你怎么转出ASCII?

0000的话字符串就断了,何况ff,ff这种就是不是任何字符的ASCII转换不了,自然就错了。

你要是能告诉我reg命令导入REG_NONE如何处理用HEX格式而不要字符串格式我就能转。



至于
1、希望保留所有数据。

你的数据不合法,一个字符串类型不能用换行符号。。。如果你要换行用REG_MUILT_SZ
但是这个导出的会是HEX格式。

我的转换会只保留第一行数据,但是由于你的第一行数据结尾没有"所以会少一个字符(Inc. All rights reserved.的最后的点掉了。)。
用reg文件直接导入的话如果你的格式是
"xx"="xxxxx
后面没"的话,reg文件就没导入数据。

我尽量按照reg文件的导入效果处理。所以这个只有你自己写合法的格式。

我的代码不去除字符串的空格。只有hex的数据导出自动换行了
   xx,xx\
   xx,xx
这种格式的前面空格会去掉。

所以是你的格式不正确。

注释保留这个建议不错。
但是因为
hex(2):31,00\
;22,00\
32,00

这样的话,这个注释在数据中间所以难处理,要数据正确只能忽略掉。

先询问BAT文件这个的确是我的忽略,下次更新会放到前面,自己该的话将
bat文件处理,哪里前2句放到注册表文件打开处理之后。


文件头当初也打算不要,但是如果你选择其他的文件根本不是reg内容的话,要是你选个小说?按行处理找[,@,"开头的。。。其实浪费了很多时间。。。还是没有转换出什么内容。所以简单的用REGEDIT4和5判断下,而且也符合reg文件的。

reg文件你不加,就不会处理。

如果要改,删除那几行就行了。

下次更新会引入个常量。。。自己设置下True或者False决定时候判断文件头。
作者: aries215     时间: 2009-12-3 10:33
经你这么解释,我大概知道REG_NONE和ASCII是怎么一回事了。这方面我要再进修一下。

你说字符串类型用换行符号是“不合法”,让我觉得概念清晰很多!我原本只是觉得这种数据比较“少见”,而且就数据本身也只是Real 插件的信息,没什么重要意义,“偷工减料”应该也不影响执行。哦~~原来这叫“不合法”,O(∩_∩)O哈!

下面这种数据我本人没碰到过,真有这样的注册表数据?
hex(2):31,00\
;22,00\
32,00
一般都是两个命令之间才作注释的。如果要正确处理这种“少见”的数据,可能要把这VBS的逻辑判断搞得很复杂。不过,对于我这种不会做又想用的人来说,不管哪方面再复杂也希望有人能做得出来,  -  - !!!

关于文件头,我个人觉得,是 .reg 后缀的几乎可以100%肯定其内容就是注册表项了,不是的几率几乎为零,有便是刻意修改的。我们事先已经指定了reg目标文件,然后再定义保存的文件名,经过这两关还会搞错的几率相当小。用命令行形式转换也是这样。我甚至觉得,判断也大可不必,后缀名没搞错就可以直接转换。

O(∩_∩)O谢谢!

[ Last edited by aries215 on 2010-10-8 at 18:35 ]
作者: aries215     时间: 2009-12-3 10:48
啊,对了,建议增加计算不可转换的REG_NONE的数量,然后告诉用户(也可以通过弹窗),这样用户就能自行处理了。可以提高数据处理的正确性。
否则,照当前的处理结果可能会造成某些麻烦,特别是数据量庞大,这些项又在中间……
我个人的想法是,可以把这些不能转的项完整复制过来,然后用“rem ”注释掉,这些注释在高级文本编辑器里会以不同颜色显示,用户很容易发现,也能很快做出相应处理。
作者: aries215     时间: 2009-12-3 11:00
还有,请问,VBS命令参数的数量有没有限制?会不会出现“命令参数太多”的情况?
我上面的某些建议,也许其他人有不同的意见,也可以做成命令参数的方式,供不同情况的人自行选择。
作者: slore     时间: 2009-12-3 13:54
命令行不过滤reg文件类型,这个因为需求可能不同,也许要转一个txt文本,内容是reg的呢,所以在参数传递的时候没有限制文件类型,只是判断文件是否存在还有文件的编码。


这类偏好不同的,是打算做成参数的。。。
对不支持的格式以后会rem输出


hex(2):31,00\
;22,00\
32,00

reg文件能导入,得到的是31,00,32,00
出现的情况,可能一个值设置不同的数据有不同的效果,下次得到

31,99,22,00的话,就可以把
;放到32前面,22这行的去掉。。。

明天或者周末更新.
作者: aries215     时间: 2009-12-3 15:21
吼吼~~
辛苦了!O(∩_∩)O谢谢!
作者: aries215     时间: 2009-12-3 19:02
有个地方忘了处理(上一版好像没有这问题):

原键值是:

  Quote:
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A0427FCE-9B13-4941-A194-3C6035260BDD}\1.0\HELPDIR]
@="D:\\Program Files\\PPStream\\"

转换后,路径最后还有“\\”:

  Quote:
reg add "HKLM\SOFTWARE\Classes\TypeLib\{A0427FCE-9B13-4941-A194-3C6035260BDD}\1.0\HELPDIR" /ve /d "D:\Program Files\PPStream\\" /f

[ Last edited by aries215 on 2009-12-3 at 19:42 ]
作者: aries215     时间: 2009-12-3 19:19
提到路径,希望增加支持转换成环境变量的功能。Reg2Inf.exe 有这个命令,是“/RepVars” 。
其实,没有也没关系,我们可以自己手工替换。如果楼主有空,也可以增强一些功能。

最常用的环境变量可能是:
1、用户目录,%userprofile%
2、系统目录,%SystemRoot% 及 system32 ;
3、程序目录,%ProgramFiles% ;
4、当前目录,%cd% 和 %~dp0

复杂一点的应该是用户目录和当前目录,绿化软件的时候比较有用。


PS:对于你的“Reg2Bat.vbs” ,我更喜欢转换成 Cmd 格式,所以代码做了替换,区分大小写,分两次进行:“Bat” ---> “Cmd” ,“bat” ---> “cmd” 。目前没发现异常,不会因此产生BUG吧?

[ Last edited by aries215 on 2009-12-3 at 19:54 ]
作者: aries215     时间: 2009-12-3 20:20
老实说,我最希望的是解决ASCII编码的问题,解决了能很好地增强工具的适用性。

[ Last edited by aries215 on 2009-12-4 at 21:04 ]
作者: slore     时间: 2009-12-4 19:15
HEX类型存储的是UNICODE编码。

所有的ANSI编码的字符都有对应的UNICODE编码,但是UNICODE编码的,ANSI编码不一定有。所以是根本不能转换的,还有自己在注册表编辑器新建,你只有那几种常用的数据格式。
没测试将REG_NONE格式用REG_BINARY写,读取的结果是否一样。
所以部分转换可以进行,比如REG_MUILT_SZ这个是多行字符串,所以如果数据正确都是可以转换的字符串,而REG_NONE存入的是字符串么?不是的话,谁也没有办法保证其数据都可以转换为ANSI。你在注册表编辑器默认的数据中看到过0x10这种类型么?REG_NONE这种类型的注册表键值有么?



REG_EXPAND_SZ类型允许使用环境变量。。。干嘛不用这种格式?


有个地方忘了处理(上一版好像没有这问题):

原键值是:


  Quote:
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A0427FCE-9B13-4941-A194-3C6035260BDD}\1.0\HELPDIR]
@="D:\\Program Files\\PPStream\\"



转换后,路径最后还有“\\”:


  Quote:
reg add "HKLM\SOFTWARE\Classes\TypeLib\{A0427FCE-9B13-4941-A194-3C6035260BDD}\1.0\HELPDIR" /ve /d "D:\Program Files\PPStream\\" /f

你有运行过再在注册表编辑器打开看过么?


要不是reg命令中反斜杠和引号的转义有特殊关系,脚本会快很多,对这个的处理得遍历字符串。处理这个的过程在转换过程中最为复杂。


喜欢CMD格式的话,只要修改最后保存为批处理段的代码的bat为cmd。

变量BatXXX这种是变量名字,如果全替换掉无所谓。要是少替换的话可能会出错。
作者: aries215     时间: 2009-12-4 21:41
哦~~原来是这样,明白了!
O(∩_∩)O谢谢!!!
作者: slore     时间: 2009-12-6 16:37
09-12-06更新。

1.选择注册表文件后立即选择要保存的批处理文件
2.对;开头的注释信息在bat中以rem开头保留下来
3.批处理文件扩展名可以在常量中定义
4.增加或略文件头检测参数
作者: aries215     时间: 2009-12-6 19:02
接近完美了,超级有用的工具!楼主功德无量!!!
辛苦了~!O(∩_∩)O谢谢!
作者: aries215     时间: 2009-12-6 22:11
新参数“/NH”好像有个问题,我的注册表文件未修改过的,用上一版的VBS可以转换,这个版本不加这参数也可以转换,加了就不行了。

作者: slore     时间: 2009-12-7 10:33
失误。定义为常量了。。


Const IgnoreRegHead = False      '忽略注册表文件头检测

改为

Dim IgnoreRegHead
IgnoreRegHead = False      '忽略注册表文件头检测

在顶楼更新。

选择批处理文件支持bat和cmd,设置bat为默认扩展名,如果扩展名为bat和cmd就不变,如果没有就加上默认扩展名。

[ Last edited by slore on 2009-12-7 at 10:58 ]
作者: aries215     时间: 2009-12-7 11:04
O(∩_∩)O
已更新,谢谢!

[ Last edited by aries215 on 2009-12-7 at 11:39 ]
作者: slore     时间: 2009-12-7 11:23
326行         MsgBox objStreamR.Size

这个是多余的。。。测试用的忘了删除了。你删除就可以了。
作者: slore     时间: 2009-12-9 17:56
REG_NONE转为REG_BINARY格式?
作者: aries215     时间: 2009-12-9 18:06
我试了一下,REG_NONE的数据仅仅去掉“,”和"\",类型名字不变的话,这个Bat写进去后数值已经不同了。

[ Last edited by aries215 on 2009-12-9 at 19:07 ]
作者: aries215     时间: 2009-12-9 18:09
对于REG_NONE,哪一种能够转换哪一种不能转换的情况,能不能判断得出来?能不能分开处理呢?
作者: aries215     时间: 2009-12-9 18:15
REG_NONE转为REG_BINARY格式不知道会不会影响程序运行,马上试一下。
因为有些REG_NONE数据导出来的数字和字母跟在注册表里一样,没变化。如果不影响程序运行,应该可以这样转换。
作者: aries215     时间: 2009-12-9 19:06
测试了IDM下载软件:
在导出来的REG文件中,“hex(0)”直接改为了“hex(3)”,然后合并注册表,启动和下载都正常,在配置界面和弹窗所显示的路径也准确。
建议可以加一个命令参数,对于“51,75,65 ......”开头的可以转为REG_BINARY格式,包括类型名字。

我试着把“hex(0)”直接替换为“hex(2)”,导入合并后,有些键的数据变成了直观的路径,但有些则好像变成了“乱码”。

[ Last edited by aries215 on 2009-12-9 at 20:22 ]
作者: aries215     时间: 2009-12-9 20:37
下面这段代码,我把原来的“hex(0)”改为“hex(3)”后,无法完成转换。
CODE:  [Copy to clipboard]
REGEDIT4

[HKEY_CURRENT_USER\Software\DownloadManager\ListSettings]
"evDownloadComplete"=hex(3):44,6f,77,6e,6c,6f,61,64,20,63,6f,6d,70,6c,65,74,65,\    00,99,7c,6f,3e,93,7c,62,3e,93,7c,08,02,00,00,e4,f8,12,00,d0,f8,12,00,8a,00,\    00,00,18,ee,92,7c,70,09,93,7c,c0,e4,99,7c,6f,3e,93,7c,46,f6,12,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\    00,00,00,00,00,00,00,00
提示:

  Quote:
Reg2Cmd.vbs(275, 1) Microsoft VBScript 运行时错误: 无效的过程调用或参数

其中,(275, 1) = objFile.Write CmdStr

原来没修改Hex就没出错,请问这算不算问题?

[ Last edited by aries215 on 2009-12-9 at 20:42 ]
作者: slore     时间: 2009-12-9 23:11
。。。

REG_BINARY类型如果是用注册表导出的话是
hex:
不带(3)的

就像HEX(1)表示的是字符串类型,导出的话直接显示字符串而不是HEX格式的。

你改为:
REGEDIT4

[HKEY_CURRENT_USER\Software\DownloadManager\ListSettings]
"evDownloadComplete"=hex:XX,XX,XX
作者: aries215     时间: 2009-12-11 21:44
谢谢!周末愉快!
作者: aries215     时间: 2009-12-14 01:53
资料显示:“REG_NONE是未定义的类型,跟REG_UNKNOWN不一样”。在注册表里是不可以新建“REG_NONE”数据的,因此我认为,“REG_NONE”都对应着某一种具体数据类型,一定是其中某一种。
用命令脚本工具处理REG_NONE数据的时候,应该是先根据数据形式分类,给它定义一个明确的类型,然后再按照该类型的处理方式来转换,而不是直接考虑把REG_NONE转换成某一种编码或进制。

[ Last edited by aries215 on 2009-12-14 at 01:55 ]
作者: slore     时间: 2009-12-14 11:55
/t       RegKey 数据类型
          [ REG_SZ    | REG_MULTI_SZ  | REG_DWORD_BIG_ENDIAN    |
            REG_DWORD | REG_BINARY    | REG_DWORD_LITTLE_ENDIAN |
            REG_NONE  | REG_EXPAND_SZ ]

是定义过的类型。

怎么说呢?所以说只处理常用类型。
还有很多类型根本你建立不了,不用reg文件的话,比如7,8

不要再纠结了。

如果你是导出的注册表文件是没有那些乱七八糟的类型的。
作者: aries215     时间: 2009-12-14 14:37
哦~~那就算了!
作者: shim     时间: 2010-10-10 23:59
楼主好!现在发布的是最新版吗?
作者: ql1307096     时间: 2010-10-11 09:58
非常好啊,正到处找呢!
作者: 8905438     时间: 2010-10-20 01:49
感谢分享,最近在正需要呢
作者: liuzhaoyzz     时间: 2017-2-21 09:46
一路找到这里,谢谢Slore分享源代码!




欢迎光临 中国DOS联盟论坛 (http://cndos.fam.cx/forum/) Powered by Discuz! 2.5