Windows vbs脚本在86上工作,但在64上失败
该脚本可以在x86上运行,但不能在x64上创建文件 有人能理解并解释原因吗 脚本正在搜索注册表,卸载注册表项,并检查displayname是否与我搜索的内容相同,然后获取productcode,并保存到一个文件,然后复制到我设置的远程共享Windows vbs脚本在86上工作,但在64上失败,windows,vbscript,x86,64-bit,Windows,Vbscript,X86,64 Bit,该脚本可以在x86上运行,但不能在x64上创建文件 有人能理解并解释原因吗 脚本正在搜索注册表,卸载注册表项,并检查displayname是否与我搜索的内容相同,然后获取productcode,并保存到一个文件,然后复制到我设置的远程共享 On error resume Next Dim strName, WshShell, oReg, keyname, WshNetwork, ComputerName Set fso = CreateObject("Scripting.FileSystem
On error resume Next
Dim strName, WshShell, oReg, keyname, WshNetwork, ComputerName
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.Shell")
Set WshNetwork = WScript.CreateObject("WScript.Network")
Const HKEY_LOCAL_MACHINE = &H80000002
Const ForReading = 1, ForWriting = 2, ForAppending = 8
ComputerName = WshNetwork.ComputerName
FileName = ComputerName & "_data.txt"
'FileName = "sep_data.txt"
'=============================================
'Chage the value here with DisplayName's value
strName = "Symantec Endpoint Protection"
'=============================================
'currentDirectory = Left(WScript.ScriptFullName,(Len(WScript.ScriptFullName))-(Len(WScript.ScriptName)))
currentDirectory = "c:\windows\temp\"
'set location in registry we want to get data from
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ComputerName & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
'check each key in uninstall for any display name called Symantec Endpoint Protection
For Each subkey In arrSubKeys
keyname = ""
keyname = wshshell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & subkey & "\DisplayName")
If keyname = strName then
i = subkey
End If
' Writes text to file if it exists
If i Then
'open text file for writing
Set filetxt = fso.OpenTextFile(currentDirectory & FileName, 2, True)
'write to text file
filetxt.WriteLine "" & computerName & "," & i & ""
'Close file
filetxt.Close
'Copy file to network share
fso.CopyFile "c:\windows\temp\" & FileName & "", "\\hostname\test\", true
End If
Next
Set WshShell = Nothing
Set ObjReg = Nothing
Set computerName = Nothing
Set i = Nothing
WScript.Quit
您可以找到原因(简而言之,注册表中的32位和64位有单独的结构,文件系统访问被重定向)
如果应用程序/注册表为32位,请使用32位脚本主机版本启动脚本(在64b操作系统版本中,32b可执行文件位于%systemroot%\SysWOW64
下)
相反的问题是,您有一个32位的进程,但是您需要访问64位注册表,需要启动一个64位的进程,这里情况会发生变化
虽然%systemroot%\System32
中的可执行文件是64位的,但由于当前进程是32位的,它在注册表和文件系统重定向下运行,并且对%systemroot%\System32
的任何引用都转换为对%systemroot%\SysWOW64
的引用(32位进程需要32位操作系统)。这可以通过使用
"%systemroot%\sysnative\cscript.exe" myscript.vbs
是的,如果从64位进程中搜索sysnative
文件夹,您将找不到它,但从32位进程中,您可以访问64位system32
文件夹
已编辑以包含变通方法。基本思想是尝试使用当前引擎查找所需信息。如果未找到,脚本将使用其他主机重新启动自身
Option Explicit
Const HKEY_LOCAL_MACHINE = &H80000002
Const ForReading = 1 _
, ForWriting = 2 _
, ForAppending = 8
Const UNINSTALL_KEY_PATH = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Const KEY_DISPLAY_NAME = "Symantec Endpoint Protection"
Const TARGET_FOLDER = "C:\TEMP"
Const ARGUMENT_FLAG = "_CHILD_"
Dim shell
Set shell = WScript.CreateObject("WScript.Shell")
Dim retValue, alternateHost
If Not WScript.Arguments.Named.Exists(ARGUMENT_FLAG) Then
retValue = shell.Run( quote(WScript.FullName) & " " & quote(WScript.ScriptFullName) & " /" & ARGUMENT_FLAG, 0, True )
If retValue > 0 Then
With WScript.CreateObject("Scripting.FileSystemObject")
If .GetFile( WScript.FullName ).ParentFolder.Name = "SysWOW64" Then
alternateHost = "\sysnative\"
Else
alternateHost = "\SysWOW64\"
End If
alternateHost = .BuildPath( shell.ExpandEnvironmentStrings("%systemroot%") & alternateHost, "cscript.exe" )
If .FileExists( alternateHost ) Then
Call shell.Run( quote(alternateHost) & " " & quote(WScript.ScriptFullName) & " /" & ARGUMENT_FLAG, 0, True )
End If
End With
End If
WScript.Quit
End If
Dim reg
Set reg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
Dim subKeys, subKey, value, keyFound
keyFound = False
reg.EnumKey HKEY_LOCAL_MACHINE, UNINSTALL_KEY_PATH, subKeys
For Each subKey In subKeys
reg.GetStringValue HKEY_LOCAL_MACHINE, UNINSTALL_KEY_PATH & "\" & subkey , "DisplayName", value
If Not IsNull( value ) Then
If value = KEY_DISPLAY_NAME Then
keyFound = True
Exit For
End If
End If
Next
Dim computerName, baseName, fileName, exitCode
If keyFound Then
computerName = WScript.CreateObject("WScript.Network").ComputerName
baseName = computerName & "_data.txt"
With WScript.CreateObject("Scripting.FileSystemObject")
fileName = .BuildPath( shell.ExpandEnvironmentStrings("%temp%"), baseName )
.CreateTextFile( fileName, True ).WriteLine( computerName & "," & KEY_DISPLAY_NAME )
.CopyFile fileName, .BuildPath( TARGET_FOLDER, .GetFile( fileName ).Name )
End With
exitCode = 0
Else
exitCode = 1
End If
Call WScript.Quit( exitCode )
Function quote( text )
quote = """" & text & """"
End Function
您可以找到原因(简而言之,注册表中的32位和64位有单独的结构,文件系统访问被重定向)
如果应用程序/注册表为32位,请使用32位脚本主机版本启动脚本(在64b操作系统版本中,32b可执行文件位于%systemroot%\SysWOW64
下)
相反的问题是,您有一个32位的进程,但是您需要访问64位注册表,需要启动一个64位的进程,这里情况会发生变化
虽然%systemroot%\System32
中的可执行文件是64位的,但由于当前进程是32位的,它在注册表和文件系统重定向下运行,并且对%systemroot%\System32
的任何引用都转换为对%systemroot%\SysWOW64
的引用(32位进程需要32位操作系统)。这可以通过使用
"%systemroot%\sysnative\cscript.exe" myscript.vbs
是的,如果从64位进程中搜索sysnative
文件夹,您将找不到它,但从32位进程中,您可以访问64位system32
文件夹
已编辑以包含变通方法。基本思想是尝试使用当前引擎查找所需信息。如果未找到,脚本将使用其他主机重新启动自身
Option Explicit
Const HKEY_LOCAL_MACHINE = &H80000002
Const ForReading = 1 _
, ForWriting = 2 _
, ForAppending = 8
Const UNINSTALL_KEY_PATH = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Const KEY_DISPLAY_NAME = "Symantec Endpoint Protection"
Const TARGET_FOLDER = "C:\TEMP"
Const ARGUMENT_FLAG = "_CHILD_"
Dim shell
Set shell = WScript.CreateObject("WScript.Shell")
Dim retValue, alternateHost
If Not WScript.Arguments.Named.Exists(ARGUMENT_FLAG) Then
retValue = shell.Run( quote(WScript.FullName) & " " & quote(WScript.ScriptFullName) & " /" & ARGUMENT_FLAG, 0, True )
If retValue > 0 Then
With WScript.CreateObject("Scripting.FileSystemObject")
If .GetFile( WScript.FullName ).ParentFolder.Name = "SysWOW64" Then
alternateHost = "\sysnative\"
Else
alternateHost = "\SysWOW64\"
End If
alternateHost = .BuildPath( shell.ExpandEnvironmentStrings("%systemroot%") & alternateHost, "cscript.exe" )
If .FileExists( alternateHost ) Then
Call shell.Run( quote(alternateHost) & " " & quote(WScript.ScriptFullName) & " /" & ARGUMENT_FLAG, 0, True )
End If
End With
End If
WScript.Quit
End If
Dim reg
Set reg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
Dim subKeys, subKey, value, keyFound
keyFound = False
reg.EnumKey HKEY_LOCAL_MACHINE, UNINSTALL_KEY_PATH, subKeys
For Each subKey In subKeys
reg.GetStringValue HKEY_LOCAL_MACHINE, UNINSTALL_KEY_PATH & "\" & subkey , "DisplayName", value
If Not IsNull( value ) Then
If value = KEY_DISPLAY_NAME Then
keyFound = True
Exit For
End If
End If
Next
Dim computerName, baseName, fileName, exitCode
If keyFound Then
computerName = WScript.CreateObject("WScript.Network").ComputerName
baseName = computerName & "_data.txt"
With WScript.CreateObject("Scripting.FileSystemObject")
fileName = .BuildPath( shell.ExpandEnvironmentStrings("%temp%"), baseName )
.CreateTextFile( fileName, True ).WriteLine( computerName & "," & KEY_DISPLAY_NAME )
.CopyFile fileName, .BuildPath( TARGET_FOLDER, .GetFile( fileName ).Name )
End With
exitCode = 0
Else
exitCode = 1
End If
Call WScript.Quit( exitCode )
Function quote( text )
quote = """" & text & """"
End Function
我使用了另一种方法将文件移动到共享。64位操作系统丢失的原因是我的reg查询调用。最后缺少/reg64。我使用了另一种方法将文件移动到共享。64位操作系统丢失的原因是我的reg查询调用。结尾处缺少/reg64。
下一步
缺少,请修复代码或粘贴整个脚本。您可以尝试在脚本的第一行调用CheckOSx86x64Args
,如fixed,谢谢您指出。删除“下一步出错时继续”,现在您可以找到原因。我现在就试试,谢谢您!更新到follow我看到它在读取某些子键时有一些问题,这很好。我真的只针对一个关键,我知道有读访问权。我还可以尝试什么?下一步
缺失,请修复代码,或粘贴整个脚本。您可以尝试在脚本的第一行调用CheckOSx86x64Args
,如fixed,谢谢您指出。删除“下一步出错时继续”,现在您可以找到原因。我现在就试试,谢谢您!更新到follow我看到它在读取某些子键时有一些问题,这很好。我真的只针对一个关键,我知道有读访问权。我还可以尝试什么?我按照建议运行,但它在64位中仍然不起作用。如果我双击vbs文件,它会工作,但我通过SCCM或DesktopCentral或EXE/MSI运行它,它会失败。当然是奇怪的问题。@3264那么你的问题可能正好相反。请尝试使用%windir%\sysnative\cscript.exe“myscript.vbs
检查一下。。是否更新为遵循sysnative?这对我来说是新的,我通常只使用%SystemRoot%\System32\cscript.exe
@Lankymart,在文件系统重定向下,32位进程将看不到真正的64位System32
。对system32
的请求被重定向到我按照建议运行的SysWoW64
,但它在64位中仍然不起作用。如果我双击vbs文件,它会工作,但我通过SCCM或DesktopCentral或EXE/MSI运行它,它会失败。当然是奇怪的问题。@3264那么你的问题可能正好相反。请尝试使用%windir%\sysnative\cscript.exe“myscript.vbs
检查一下。。是否更新为遵循sysnative?这对我来说是新的,我通常只使用%SystemRoot%\System32\cscript.exe
@Lankymart,在文件系统重定向下,32位进程将看不到真正的64位System32
。对system32
的请求被重定向到SysWoW64