标题: [问题求助] [已解决]VBS如何读取unicode编码的inf文件里等号后面的内容 [打印本页]
作者: yuanyannian 时间: 2014-10-28 07:47 标题: [已解决]VBS如何读取unicode编码的inf文件里等号后面的内容
本帖最后由 pcl_test 于 2016-8-14 11:48 编辑
求助---VBS如何读取 inf 文件等号后面的内容 并赋给变量
问题描述:还是处理 unicode 格式的 inf 文件,比如:
aaa.inf
[Strings]
BIOS = "abcd-abcd"
TIDS = ABCD
用 vbs (也要求是 unicode 格式)读取 BIOS 及 TIDS 等号后面的内容,并分别赋给变量 str1 和 str2
谢谢!
作者: yuanyannian 时间: 2014-10-28 13:26
回复 1# yuanyannian
是不是这个问题太幼稚?
作者: yu2n 时间: 2014-10-28 14:30
- ' 读INI文件
- strIniFile = ".\test.inf"
- strBIOS = ReadINI(strIniFile, "Strings", "BIOS")
- strTIDS = ReadINI(strIniFile, "Strings", "TIDS")
- MsgBox "BIOS = " & strBIOS & vbCrLf & "TIDS = " & strTIDS, vbInformation
-
- ' read函数
- Function ReadINI(FilePath, Bar, PrimaryKey)
- Dim fso, sReadLine, i, j, ss
- Set fso = CreateObject("Scripting.FileSystemObject")
- Set IniFile = fso.opentextfile(FilePath, 1,-1)
- Do Until IniFile.atendofstream
- sReadLine = IniFile.readline
- If sReadLine = "" Then
- IniFile.skipline
- ElseIf Trim(sReadLine) = "[" & Bar & "]" Then '找到小节名
- '查找该小节名下的键名
- Do Until IniFile.atendofstream
- sReadLine = IniFile.readline '读取小节名后的行
- j = InStr(sReadLine, "=")
- If j > 0 Then '小节名后的文本行存在
- If InStr(Left(sReadLine, j), PrimaryKey) > 0 Then '从"="左边字符串找到键名
- ss = Trim(Right(sReadLine, Len(sReadLine) - InStr(sReadLine, "="))) '读取等号后的部分
- Exit Do
- End If
- End If
- Loop
- End If
- Loop
- IniFile.Close
- Set fso = Nothing
- ReadINI = ss
- End Function
复制代码
作者: yuanyannian 时间: 2014-10-28 17:24
回复 3# yu2n
谢谢,试了一下,但读不出啊。
作者: zz100001 时间: 2014-10-28 17:51
这种情况你就把你实际的那个文件和vbs都放到附件里面来
他发这么一个东西可能自己也试过一下的
有可能你那编码就不是unicode,而是utf-8之类的
作者: yuanyannian 时间: 2014-10-28 19:48
回复 3# yu2n
上传需要处理的原文件,请老师给看一下。
文件大点,给个地址:
HIVESFT.rar
http://pan.baidu.com/s/1mgl24dy
作者: yu2n 时间: 2014-10-28 22:40
回复 6# yuanyannian
思密达文字可能不兼容中文系统的 fso.opentextfile(file, 1,-1) Unicode 编码,我换 ADODB.Stream Unicode 测试OK。- strIniFile = "V:\HIVESFT.INF"
- strBIOS = ReadINI(strIniFile, "Strings", "BIOS")
- strTIDS = ReadINI(strIniFile, "Strings", "NDIS")
- strInfo = "BIOS = " & strBIOS & vbCrLf & "NDIS = " & strTIDS
- Msgbox strInfo, vbInformation
-
- Function ReadIni(strIniFilePath, strPrimary, strSubKey)
- Dim objStream
- Set objStream = CreateObject("ADODB.Stream")
- With objStream
- .Type = 2
- .Mode = 3
- .Open
- .Charset = "Unicode"
- .LoadFromFile strIniFilePath
- strText = .ReadText
- .Close
- End With
- Set objStream = Nothing
- arrText = Split(strText, vbCrLf)
- For Each strLine In arrText
- If intCount = 0 Then
- If strLine = "[" & strPrimary & "]" Then
- intCount = 1
- End If
- Else
- If Left(strLine,1) = "[" Then Exit For
- j = InStr(strLine, "=")
- If j > 0 Then '小节名后的文本行存在
- If InStr(Left(strLine, j), strSubKey) > 0 Then '从"="左边字符串找到键名
- ReadIni = Trim(Right(strLine, Len(strLine) - InStr(strLine, "="))) '读取等号后的部分
- Exit For
- End If
- End If
- End If
- Next
- End Function
复制代码
作者: yuanyannian 时间: 2014-10-29 06:27
本帖最后由 yuanyannian 于 2014-10-29 06:30 编辑
回复 7# yu2n
再次感谢了。
这样可以了,但问题又来了:就思密达而言,将读出的变量写入注册表,都成了“?????????”,请老师给看一下。
另外,不能读如:STANGDARD_NAME、KLT_63 等格式的变量。
作者: yu2n 时间: 2014-10-29 11:37
回复 8# yuanyannian
1. 你是如何写入注册表的?
建议注册表使用 regedit.exe /s abc.reg 的形式写入,其中 abc.reg 为Unicode编码。
2. 你将代码14行的Unicode编码改为其他编码试试。
作者: yuanyannian 时间: 2014-10-29 12:23
本帖最后由 yuanyannian 于 2014-10-29 12:29 编辑
回复 9# yu2n
直接在 vbs 中:
Set Reg=WScript.CreateObject("WScript.Shell")
Reg.RegWrite "HKCU\yyn\Desktop\Wallpaper",strBIOS,"REG_SZ"
如果用 .reg ,需要用vbs先写入到 .reg 文件,而且必须是 unicode 格式,这个我不会,老师可否帮一帮?
作者: yu2n 时间: 2014-10-29 14:01
回复 10# yuanyannian
读写Unicode文本:- Function WriteUnicodeText(File, TextString)
- With CreateObject("ADODB.Stream")
- .Type = 2 : .Mode = 3 : .Charset = "Unicode" : .Open
- .WriteText TextString : .SaveToFile File, 2 : .Close
- End With
- End Function
-
- Function ReadUnicodeText(File)
- With CreateObject("ADODB.Stream")
- .Type = 2 : .Mode = 3 : .Charset = "Unicode" : .Open
- .LoadFromFile File : ReadUTF8Text = .ReadText : .Close
- End With
- End Function
复制代码
作者: yuanyannian 时间: 2014-10-29 17:40
回复 11# yu2n
抱歉,看不太懂,请帮写一个代码?
作者: yu2n 时间: 2014-10-29 19:03
回复 12# yuanyannian
函数 WriteUnicodeText(File, TextString)
功能:将字符串以Unicode编码写入文本文件。
参数:File 为文本文件路径,TextString 为字符串。
函数 ReadUnicodeText(File, TextString)
……你一定是在逗我,这个就不解释了。
作者: yuanyannian 时间: 2014-10-29 21:25
回复 13# yu2n
抱歉,我是真的不会,前一阵子还在论坛中求助过,是可以创建一个文件,但只能全新覆盖写入,不能追加写入。
请老师帮忙,谢谢!
作者: yu2n 时间: 2014-10-29 23:47
回复 14# yuanyannian
追加写入?
1. 读取旧文本,保存为字符串 str1
2. 将要保存的字符串 str2 与字符串 str1 合并为 str3 。(字符串使用 & 连接符)
3. 向文件写入 str3 ,即完成追加写入。- File = "d:\abc.txt"
- str1 = ReadUnicodeText(File) ' 读取
- str2 = " 我是新字符串 " ' 新字符串
- str3 = str1 & str2 ' 合并新旧字符串(追加)
- WriteUnicodeText File, str3 ' 写入文件
复制代码
作者: apang 时间: 2014-10-30 00:33
本帖最后由 apang 于 2014-10-30 09:40 编辑
我这里ws.regwrite写入是问号,wmi写入正常,试试看- Dim fso, txt, re, m, regPath, regValue, regData
- Set fso = CreateObject("Scripting.FileSystemObject")
- txt = fso.OpenTextFile("HIVESFT.INF", 1, false, -1).ReadAll
- txt = txt & vbCrLf & "["
-
- Set re = New RegExp
- re.Pattern = "^ *\[Strings] *$[\s\S]*?(?=^ *\[)"
- re.IgnoreCase = true
- re.Global = true
- re.MultiLine = true
- If Not re.Test(txt) Then WScript.Quit
- txt = re.Execute(txt)(0)
- re.Pattern = "^ *(BIOS|NDIS) *= *(.+)"
- For Each m in re.Execute(txt)
- regPath = "yyn\Desktop"
- regData = Replace(m.SubMatches(1), chr(34), "")
- If UCase(m.SubMatches(0)) = "BIOS" Then
- regValue = "yyn1"
- Else
- regValue = "yyn2"
- End If
- WriteToRegValue regPath, regValue, regData
- Next
-
- Sub WriteToRegValue(ByVal regPath, ByVal regValue, ByVal regData)
- Const HKCU = &H80000001
- Dim regWMI
- Set regWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\Default:StdRegProv")
- regWMI.CreateKey HKCU, regPath
- regWMI.SetStringValue HKCU, regPath, regValue, regData
- End Sub
复制代码
作者: yuanyannian 时间: 2014-10-30 06:46
本帖最后由 yuanyannian 于 2014-10-30 06:51 编辑
回复 16# apang
谢谢 apang 老师出手,读、写均正常。
不过,我的需求是:只读出 = 后面的内容作为变量,写入注册表中的路径、键值是需要自定义的,比如 HKCU\yyn\Desktop, yyn(键值), BIOS 或 NDIS (还有很多其它的) = 后面的内容(数据), 或者如注册表文件:
[HKEY_CURRENT_USER\yyn\Desktop]
"yyn1"="대한민국 표준시"
"yyn2"="한국어"
或:
[HKEY_CURRENT_USER\yyn\System\Test]
"yyn3"="한국어 입력 시스템 (IME 2000)"
"yyn4"="한"
或者将读出的数据分别写成注册表文件,再自行导入注册表也可。比如写成注册表文件 (unicode 格式):
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\yyn\Desktop]
"yyn1"="대한민국 표준시"
"yyn2"="한국어"
[HKEY_CURRENT_USER\yyn\System\Test]
"yyn3"="한국어 입력 시스템 (IME 2000)"
"yyn4"="한"
有劳 apang 老师了。
作者: apang 时间: 2014-10-30 09:43
回复 17# yuanyannian
已修改,如果想自定义,更改相应变量的值即可
作者: yuanyannian 时间: 2014-10-30 11:55
回复 18# apang
是这样吗?- Dim fso, txt, re, m, regPath, regValue, regData
- Set fso = CreateObject("Scripting.FileSystemObject")
- txt = fso.OpenTextFile("HIVESFT.INF", 1, false, -1).ReadAll
- txt = txt & vbCrLf & "["
-
- Set re = New RegExp
- re.Pattern = "^ *\[Strings] *$[\s\S]*?(?=^ *\[)"
- re.IgnoreCase = true
- re.Global = true
- re.MultiLine = true
- If Not re.Test(txt) Then WScript.Quit
- txt = re.Execute(txt)(0)
- re.Pattern = "^ *(BIOS|NDIS|NETWORK_DDE|NETWORK_DDE_DESCRIPTION|NETWORK_DDE_DSDM) *= *(.+)"
- For Each m in re.Execute(txt)
- regData = Replace(m.SubMatches(1), chr(34), "")
- If UCase(m.SubMatches(0)) = "BIOS" Then
- regPath = "yyn\Desktop"
- regValue = "yyn1"
- End If
- If UCase(m.SubMatches(0)) = "NDIS" Then
- regPath = "yyn\Desktop\yyn"
- regValue = "yyn2"
- End If
- If UCase(m.SubMatches(0)) = "NETWORK_DDE" Then
- regPath = "yyn\Test"
- regValue = "yyn3"
- End If
- If UCase(m.SubMatches(0)) = "NETWORK_DDE_DESCRIPTION" Then
- regPath = "yyn\Test\yyn"
- regValue = "yyn4"
- End If
- If UCase(m.SubMatches(0)) = "NETWORK_DDE_DSDM" Then
- regPath = "yyn\yyn\yyn"
- regValue = "yyn5"
- End If
- WriteToRegValue regPath, regValue, regData
- Next
-
- Sub WriteToRegValue(ByVal regPath, ByVal regValue, ByVal regData)
- Const HKCU = &H80000001
- Dim regWMI
- Set regWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\Default:StdRegProv")
- regWMI.CreateKey HKCU, regPath1
- regWMI.SetStringValue HKCU, regPath, regValue, regData
- End Sub
复制代码
但提示:
另外,在 re.Pattern = "^ *(BIOS|NDIS|NETWORK_DDE|NETWORK_DDE_DESCRIPTION|NETWORK_DDE_DSDM) *= *(.+)" 中,如果需要几十个变量,该如何处理?
作者: yuanyannian 时间: 2014-10-30 13:32
提示现象是我把 regWMI.CreateKey HKCU, regPath1 搞错了。
另外,我把 HKCU 改成 HKLM ,把 Const HKCU = &H80000001 改为 Const HKLM = &H80000002,失败。
作者: apang 时间: 2014-10-30 17:18
回复 19# yuanyannian
还是保存到reg文件吧,少一点弯弯绕- Dim s1, s2, strSection, arField, arValue, arPath
- s1 = "HKEY_CURRENT_USER\"
- s2 = "HKEY_LOCAL_MACHINE\"
- strSection = "Strings"
- arField = Array("BIOS", "NDIS", "GULIM")
- arValue = Array("yyn1", "yyn2", "yyn3")
- arPath = Array(s1 & "yyn\Desktop", s1 & "yyn\Test", s2 & "Software\Test\yyn")
-
- Dim fso, txt, re, i, regData
- Set fso = CreateObject("Scripting.FileSystemObject")
- txt = fso.OpenTextFile("HIVESFT.INF", 1, false, -1).ReadAll
- txt = txt & vbCrLf & "["
-
- Set re = New RegExp
- re.Pattern = "^ *\[" & strSection & "] *$[\s\S]*?(?=^ *\[)"
- re.IgnoreCase = true
- re.Global = true
- re.MultiLine = true
- If Not re.Test(txt) Then WScript.Quit
- txt = re.Execute(txt)(0)
-
- For i = 0 to UBound(arField)
- re.Pattern = "^ *" & arField(i) & " *= *("".*"")"
- If re.Test(txt) Then
- regData = re.Execute(txt)(0).SubMatches(0)
- s = s & "[" & arPath(i) & "]" & vbCrLf
- s = s & """" & arValue(i) & """=" & regData & vbCrLf
- s = s & vbCrLf
- End If
- Next
-
- s = "Windows Registry Editor Version 5.00" & vbCrLf & vbCrLf & s
- fso.OpenTextFile("Result.reg", 2, true, -1).Write s
复制代码
作者: yuanyannian 时间: 2014-10-30 17:50
这样也好,19楼的代码不能写入 HKLM 应该是对该根键没有权限造成的,路径写入 HKLM 的子键中是则可以。
再次谢谢 apang 老师。
再请问,如果不需要搜索 [strings], 去掉那些代码?
作者: apang 时间: 2014-10-30 18:17
回复 22# yuanyannian
代码是先找到 Strings 节,再在Strings节中找相应的字段。
比如 BIOS 字段,在Strings中有,在其它节也可能有。
如果去掉Strings节名,找到的可能就不正确,你希望这样吗?
作者: yuanyannian 时间: 2014-10-30 19:31
回复 23# apang
有道理,那我采用写入注册表文件。
作者: yuanyannian 时间: 2014-10-31 07:46
回复 23# apang
再麻烦 apang 老师,测试中发现一个问题:当源文件等号后面的数据没有 "" 情况下,无法读出及写入注册表文件。
作者: apang 时间: 2014-10-31 10:00
回复 25# yuanyannian
不带双引号还是 REG_SZ 类型吗?你不说清楚那我只考虑一种类型,不考虑其它类型或其它特殊情况
作者: yuanyannian 时间: 2014-10-31 10:21
回复 26# apang
是的,都是字符串 - REG_SZ 的。
作者: apang 时间: 2014-10-31 11:44
回复 27# yuanyannian
第25行下面插入一行:- regData = chr(34) & Replace(regData, chr(34), "") & chr(34)
复制代码
第23行改成:- re.Pattern = "^ *" & arField(i) & " *= *([^\r\n]+)"
复制代码
作者: yuanyannian 时间: 2014-10-31 12:00
回复 28# apang
可以了,非常感谢!
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |