2015-11-03 98 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