1

我有一个问题是基于这里提出的以前的问题。

我需要更改多台计算机上的注册表项条目,其中所述注册表项的 REG GUID 在每台计算机上都不同。我发现我可以将 regkey 提取到 .reg 或 .txt 文件中,找到“Device_State”值,然后使用类似于我上面引用的链接中的 .vbs 脚本将它们替换为我想要的值。

我不能为此使用任何第 3 方解决方案。它本质上必须是 Windows 的有机物(Windows 7 和 Windows 10 目前是我的环境)。

问题

当我将 .reg 文件放在目录中并运行(双击).vbs 脚本(从同一目录)时,我的 Test.vbs 脚本似乎可以工作。

该脚本查找并替换我想要的字符串并将其全部写回 .reg 文件(在本例中为“replace.reg”)。但是,当我从批处理文件中调用它时,.vbs 脚本会返回错误:

行:15 字符:1 错误:无效的过程调用或参数
代码:800A0005 源:Microsoft VBScrpt 运行时错误

我的代码中的第 15、1 行是:objFile.Write strNewText.

当我检查 .reg 以查看发生了什么变化时,该文件现在是空白的。似乎脚本正在将文件的内容读入strText变量,查找我的值,替换值,然后出错并且不写回 .reg 文件。

批处理文件

我的批处理文件执行以下操作:

  1. 创建一个用于备份和工作的目录

    md c:\windows\patches
    reg export "hkey_name" C:\windows\patches\backup\backup.reg
    
  2. 将注册表项导出到 .reg 文件(以及单独的 .txt 以供参考)以实际操作文件内容:

    reg export “hkey_name” c:\windows\patches\replace.reg
    reg export "hkey_name" c:\windows\patches\replace.txt
    
  3. 调用 .vbs 脚本

    @call cscript “%~dp0Test.vbs”
    

    我也试过

    runas /user:localadmin /savecred "wscript.exe c:\windows\Patches\Test.vbs"
    
  4. 将新的 .reg 导入注册表(这是计划;还没有走到这一步)。

    reg import c:\windows\patches\replace.reg
    

VBScript

Test.vbs 脚本如下:

Option Explicit
Dim objFSO, objFile, strText, strNewText
Const ForReading = 1
Const ForWriting = 2

Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objFile = objFSO.OpentTextFile(“C:\Windows\Patches\backup.reg”, ForReading)

strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText, ”HKEY”, ”BLAH-BLAH”)      '<—– this is just for testing function!
strNewText = Replace(strText, "LOCAL", "EAT_SOME_FOOD") '<—-just for testing function!

Set objFile = objFSO.OpenTextFile("C:\Windows\Patches\backup.reg", ForWriting)
objFile.Write strNewText
objFile.Close

MsgBox "Done"

因此,再次重申,当我独立运行 VBScript 时,它完全符合我的要求。但是当我从批处理文件中调用它时,它会“清除”(或无法写入)我需要更改的文件。

我以本地系统管理员的身份运行它,对相关文件拥有完全权限。

我从提升的 CMD 提示符/窗口运行它。

问题

有谁知道为什么这会独立于批处理文件工作,但在被批处理文件调用时不起作用?我认为它必须与在“内部”批处理例程中打开/关闭文件以进行读/写的权限或权限有关。我只是不够了解,无法弄清楚。

***************************** 更新 ******************** ******************

我进一步缩小了范围,这就是我的发现: -
1)我运行我的批处理文件,该文件创建了我需要编辑的注册表项的备份。批处理文件创建相同注册表项的 .reg 文件和 .txt 文件(这只是为了我自己的安全性同时拥有两者)。我还授予每个人、用户、管理员对此文件夹/文件的完全权限

2) 然后我运行查找/替换文本 vbScript。它在“objFile.Write strNewText”行出错。当它出错时,它似乎会清除 .reg 文件的内容。

3)我发现如果我将 .txt 文件中的所有内容(完全相同的文本)粘贴到 .reg 文件中(在 vbscript 错误之后)然后运行我的脚本,它就可以工作。

我尝试手动删除 .reg 内容并将其替换为 .txt 内容并尝试运行脚本,但它以同样的方式出错,并且似乎再次清除了 .reg 文件的内容。只有在写入文件时出现 VBSCRIPT 错误后,似乎清除了内容,我才能将 .txt 文件的内容粘贴到 .reg 文件中并运行 VBScript ...并且它可以工作。我对此感到很困惑。我无法想象发生了什么。拜托,我希望其他人可以帮助我。谢谢。

4

1 回答 1

1

可能会引发您看不到的错误。在您的批处理文件中,在每一行的末尾添加> output.txt,如下所示:

md c:\windows\patches
reg export "hkey_name" C:\windows\patches\backup\backup.reg > outputExport1.txt
reg export "hkey_name" c:\windows\patches\replace.reg > outputExport2.txt
reg export "hkey_name" c:\windows\patches\replace.txt > outputExport3.txt
cscript "%~dp0Test.vbs" > outputVBS.txt

这会将您在命令提示符中看到的任何错误信息转储到输出文件。或者,您可以在命令提示符下手动运行批处理文件的每一行,然后查看其中的内容。

在您的脚本中,您可以添加额外的调试输出(如果您手动运行,它们也将被转储到您的输出文件中或显示在命令提示符中):

Option Explicit
Dim objFSO, objFile, strText, strNewText
Const ForReading = 1
Const ForWriting = 2

WScript.Echo "Reading the file"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpentTextFile("C:\Windows\Patches\backup.reg", ForReading)

strText = objFile.ReadAll
WScript.Echo "File Contents: " & strText
objFile.Close
strNewText = Replace(strText, "HKEY", "BLAH-BLAH")      '<—– this is just for testing function!
WScript.Echo "Did first replace: " & strNewText 
strNewText = Replace(strNewText, "LOCAL", "EAT_SOME_FOOD") '<—-just for testing function!
WScript.Echo "Did second replace: " & strNewText      


Set objFile = objFSO.OpenTextFile("C:\Windows\Patches\backup.reg", ForWriting)
WScript.Echo "Opened the File for Writing"
objFile.Write strNewText
WScript.Echo "Wrote the File"
objFile.Close
WScript.Echo "Closed the File"    
WScript.Echo "Done"

请注意,在上面的代码中,我纠正了您在第二个代码中的一个错误Replace- 在原始代码中您正在重用strText变量,这意味着第一个代码所做的更改Replace被覆盖。

于 2017-05-11T20:02:43.763 回答