VBScript与HTA和类型不匹配错误的奇怪问题
当我通过双击运行以下脚本时,它工作得很好。它按预期方式返回最后登录的用户。但是当我从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
默认情况下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位)启动。
使用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:
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} %*
没有工作。当我将'wscript.echo strvalue'更改为'msgbox strvalue'时,我得到了一个不同的错误:无效的使用Null:strValue代码:800A005E在我改变的行上。再次通过双击运行脚本可以正常工作。通过HTA运行脚本将返回该错误。 –
几周前我有过同样的挑战。 以下代码为我提供了查看当前登录到远程计算机的人员的可能性。
我希望这可以帮助你。
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
我忘了在我的原始代码中包含常量。但它已经在那里了。再次通过双击工作正常,但通过HTA它返回一个错误。为什么它会使用一种方法而不使用另一种方法?根本没有意义。 –
就是这样!谢谢。 –