2015-11-03 126 views
2

当我通过双击运行以下脚本时,它工作得很好。它按预期方式返回最后登录的用户。但是当我从HTA运行它时,我一直在开发所有脚本的前端,在“wscript.echo strvalue”行中出现类型不匹配错误。我已经尝试了所有的工作,比如将mshta.exe的权限更改为完全控制自己。我根本无法从HTA运行而没有发生错误,但它可以像预期的那样100%运行。我完全难倒了。VBScript与HTA和类型不匹配错误的奇怪问题

strinput = "myserver" 
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ 
strinput & "\root\default:StdRegProv") 
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI" 
strValueName = "LastLoggedOnUser" 
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue 
Wscript.Echo strValue 

回答

1

默认情况下Windows 64位使用MSHTA.EXE 32位。注册表具有用于64位和32位应用程序的独立分支,因此WMI无法找到您要查找的注册表值。 将下面的代码保存为e。 G。 C:\test\tmp.hta,尝试通过双击(32位默认情况下),从资源管理器中启动它 - 你会得到null,然后通过运行对话框( + [R)与路径展开:%windir%\system32\mshta.exe "C:\test\tmp.hta"(64位),结果将是您的用户名。

<html> 
    <head> 
     <script language="vbscript"> 
      Sub window_onload() 
       Const HKEY_LOCAL_MACHINE = &H80000002 
       Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv") 
       strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI" 
       strValueName = "LastLoggedOnUser" 
       objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue 
       document.body.innerText = strValue 
      End Sub 
     </script> 
    </head> 
    <body> 
    </body> 
</html> 

请注意,脚本中的许多其他内容取决于应用程序体系结构, G。 ActiveX的数量仅在32位版本中可用,因此它们应通过%windir%\SysWOW64\(Windows 64位子系统上的Windows 32位)启动。

+0

我忘了在我的原始代码中包含常量。但它已经在那里了。再次通过双击工作正常,但通过HTA它返回一个错误。为什么它会使用一种方法而不使用另一种方法?根本没有意义。 –

+0

就是这样!谢谢。 –

1

使用Msgbox function代替Wscript.Echo方法。 HTA使用Internet Explorer脚本对象模型,其中不包含Wscript对象(此属于Windows Script Host Object Model)。

HTA: Why Can’t I Use Wscript.Echo?

You might have noticed that when it came time to report back the operating system version we used the VBScript Msgbox function rather than the more common Wscript.Echo. Why didn’t we use Wscript.Echo? Here’s why:

Error Message

As it turns out the various Wscript methods - Wscript.Echo, Wscript.Sleep, Wscript.Quit, etc. - are designed solely to run under the Windows Script Host environment. When we’re working in an HTA we’re not running under WSH; instead we’re running under the MSHTA process. Because of that the Wscript methods are not available to us (nor can we create them). Consequently we need to find workarounds for each method, and Msgbox is a perfectly adequate replacement for Wscript.Echo. (We’ll talk about workarounds for other methods - such as Wscript.Sleep - when we get to them.)

The moral of the story: Don’t bother with Wscript.Echo; it won’t work.

编辑:与Wscript.Echo TypeName(strValue) & vbNewLine & VarType(strValue)

==> C:\Windows\System32\cscript.exe D:\VB_scripts\SO\33505295.vbs 
String 
8 

==> C:\Windows\SysWOW64\cscript.exe D:\VB_scripts\SO\33505295.vbs 
Null 
1 

以简单HTA可以得到相同的(不同的)尝试导致

==> C:\Windows\System32\mshta.exe 33505295.hta 

==> C:\Windows\SysWOW64\mshta.exe 33505295.hta 

结论。检查HTA文件类型关联。例如,ftype htafile在我的Windows 8(64位)返回这将导致上双击错误的行为相同的值(令人吃惊地):

==> assoc .hta 
.hta=htafile 

==> ftype htafile 
htafile=C:\Windows\SysWOW64\mshta.exe "%1" {1E460BD7-F1C3-4B2E-88BF-4E770A288AF5}%U{1E460BD7-F1C3-4B2E-88BF-4E770A288AF5} %*  
+0

没有工作。当我将'wscript.echo strvalue'更改为'msgbox strvalue'时,我得到了一个不同的错误:无效的使用Null:strValue代码:800A005E在我改变的行上。再次通过双击运行脚本可以正常工作。通过HTA运行脚本将返回该错误。 –

1

几周前我有过同样的挑战。 以下代码为我提供了查看当前登录到远程计算机的人员的可能性。

我希望这可以帮助你。

Sub ActionGetCurrentUser(strCPU) 'strCPU is the computername 
set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strCPU & "\root\cimv2") 
    set Items = objWMI.ExecQuery("Select * From Win32_ComputerSystem") 

    For Each obj in Items 
     OutStr = right(obj.username,9) 
    Next 

    Resultstring = "Logged in User is: " & OutStr 

    Set objRootDSE = GetObject("LDAP://RootDSE") 
    strDNSDomain = objRootDSE.Get("defaultNamingContext") 
    strTarget = "LDAP://" & strDNSDomain 
' ---------------- Write the User's account & password to a variable ------------------- 
    strCurrentuser = Currentuser.value 
    strPassword = PasswordArea.value 
' ---------------- Connect to Ad Provider ---------------- 
    Set objConnection = CreateObject("ADODB.Connection") 
    objConnection.Provider = "ADsDSOObject" 
    objConnection.Properties("User ID") = strCurrentUser  ' pass credentials - if you omit this, the search is performed.... 
    objConnection.Properties("Password") = strPassword  ' ... with the current credentials 
    objConnection.Properties("Encrypt Password") = True  ' only needed if you set "User ID" and "Password" 
    objConnection.Open "Active Directory Provider" 
    Set objCmd = CreateObject("ADODB.Command") 
    Set objCmd.ActiveConnection = objConnection 

    objCmd.CommandText = "SELECT DisplayName FROM '" & strTarget & "' WHERE extensionAttribute11 = '" & OutStr & "'"  

    Const ADS_SCOPE_SUBTREE = 2 
    objCmd.Properties("Page Size") = 100 
    objCmd.Properties("Timeout") = 30 
    objCmd.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
    objCmd.Properties("Cache Results") = False 

    Set objRecordSet = objCmd.Execute 

    If objRecordset.Recordcount = 0 then ' If no user is found then the recordcount will be 0 
     msgbox "No user is logged on" 
     Resultstring = "" 
     Set objCmd = Nothing 
     Set objRootDSE = Nothing 
     Set objRecordSet = Nothing 
     Set objWMI = Nothing 
     Set Items = Nothing 
     exit sub 
    End if 

    Set objRecordSet = objCmd.Execute 

    objRecordSet.MoveFirst 

    Resultstring = Resultstring & vbcrlf & "Name: " & objRecordset.fields("DisplayName")   

    Msgbox Resultstring 

    Resultstring = "" 

    Set objCmd = Nothing 
    Set objRootDSE = Nothing 
    Set objRecordSet = Nothing 
    Set objWMI = Nothing 
    Set Items = Nothing 
End Sub