vbs脚本在86上工作但在64上失败

时间:2017-03-14 19:20:42

标签: windows vbscript x86 64-bit

该脚本适用于x86,但不会在x64上创建该文件。

谁能理解为什么并解释?

脚本正在搜索注册表,卸载密钥并检查displayname是否等于我正在搜索的内容,并获取产品代码,然后保存到一个文件,然后将其复制到我已设置的远程共享。

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

2 个答案:

答案 0 :(得分:0)

Here你可以找到为什么(简而言之,注册表中有32位和64位的单独结构,文件系统访问被重定向)

对于 how ,如果应用程序/注册表是32位,则使用32位脚本主机版本启动脚本(在64b OS版本中,32b可执行文件位于%systemroot%\SysWOW64下)

"%systemroot%\SysWOW64\cscript.exe" myscript.vbs

反问题,你有一个32位进程,但你需要访问64位注册表,需要启动一个64位进程,这里事情发生了变化。

虽然%systemroot%\System32中的可执行文件是64位,但当前进程是32位,它在注册表和文件系统重定向下运行,并且对%systemroot%\System32的任何引用都转换为对{{%systemroot%\SysWOW64的引用1}}(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

答案 1 :(得分:0)

我使用了另一种方法将文件移动到共享。为什么64位操作系统被错过是由于我的reg查询调用。最后它丢失/ reg64。