如何将退出状态从 HTA (vbscript) 返回到调用批处理文件



如何将退出状态从HTA(vbscript)返回到调用批处理文件?

我的批处理文件代码

@echo OFF
echo Configuring Test...
call AppConfigurationEditor.hta
call TestConfigurationEditor.hta

1.如果用户在第一个HTA上单击"取消"按钮,我不想运行第二个HTA。

2.批处理脚本立即调用/显示第二个 HTA,而不是等到第一个 HTA 关闭。

HTA 没有实现将错误级别返回给调用方进程的方法。

WScript.Quit不能使用。语言引擎 vbscript/javascript/...是相同的,但实例化引擎的主机对象不是惯常的 Windows 脚本主机,它是一个浏览器对象,因此WScript对象不存在。

window.close方法不能使用。它可以关闭 hta,但不提供返回值。

使用 hta 向调用进程返回值的常用方法是将此值保留在文件或注册表中。然后,调用进程可以检索所需的值。

如果需要错误级别,则没有直接的方法。但是可以实施间接方法。只需使用 WMI 检索正在运行的进程的列表,找到当前的 hta,然后为此进程调用允许设置退出值的 Terminate 方法。

<HTML>
    <HEAD>
        <HTA:APPLICATION 
            ID              = "testCloseHTA" 
            APPLICATIONNAME = "testCloseHTA"
            VERSION         = "0.1"
            NAVIGABLE       = "yes"
            SHOWINTASKBAR   = "yes" 
            SINGLEINSTANCE  = "yes" 
            WINDOWSTATE     = "normal"
            BORDER          = "normal" 
            BORDERSTYLE     = "normal"
            INNERBORDER     = "no" 
            CAPTION         = "yes" 
            MINIMIZEBUTTON  = "yes"
            MAXIMIZEBUTTON  = "yes"
            SYSMENU         = "yes" 
            SCROLL          = "yes" 
            SCROLLFLAT      = "yes"
            CONTEXTMENU     = "yes"
            SELECTION       = "yes"
        />
        <TITLE>testCloseHTA</TITLE>
        <STYLE>
            body { font-size: 1em; font-family:Verdana; }
        </STYLE>
        <SCRIPT language="Javascript">
            function closeWithErrorlevel(errorlevel){
                var colProcesses = GetObject('winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2').ExecQuery('Select * from Win32_Process Where Name = 'mshta.exe'');
                var myPath = (''+location.pathname).toLowerCase();
                var enumProcesses = new Enumerator(colProcesses);
                for ( var process = null ; !enumProcesses.atEnd() ; enumProcesses.moveNext() ) {
                    process = enumProcesses.item();
                    if ( (''+process.CommandLine).toLowerCase().indexOf(myPath) > 0 ){
                        process.Terminate(errorlevel);
                    }
                }
            }
            function closeHTA(value){
                // test close of window. Use default value
                if (typeof value === 'undefined') value = 0; 
                try { closeWithErrorlevel(value) } catch (e) {};
            }
        </SCRIPT>
    </HEAD>
    <BODY>
        <button onclick="closeHTA(0);">close application 0</button>
        <button onclick="closeHTA(1);">close application 1</button>
        <button onclick="closeHTA(2);">close application 2</button>
    </BODY>
    <script language="Javascript">
            window.attachEvent('onbeforeunload',closeHTA);
    </script>
</HTML>

然后你可以从批处理文件调用它作为

start "" /wait testCloseHTA.hta
if errorlevel 2 (
    echo option 2 has been selected
) else if errorlevel 1 (
    echo option 1 has been selected
) else (
    echo option 0 has been selected
)
@echo OFF
echo Configuring Test...
start /wait "" AppConfigurationEditor.hta
echo %errorlevel%
if %errorlevel%==0 call TestConfigurationEditor.hta

应该完成工作 - 前提是 errorlevel 返回为 0 表示terminated normally,其他返回为"取消"。

echo %errorlevel%线只是为了测试,只是向您展示发生了什么。

start /wait将启动目标,并暂停批处理,直到该过程完成。额外的一对兔子耳朵实际上包围了新的窗口标题 - 这里多余,但最好保留start否则从目标(如果有)中选择第一个带引号的字符串作为窗口标题。

您必须将

按下按钮的结果作为可以在errorlevel中恢复的Exit Code返回,并在两个 Hta 代码中Wscript.Quit [Value](或者如果您只想检查第一个,则在第一个)

示例 :

Test.vbs

result=Msgbox("Are you sure?",vbokcancel, "")
WScript.Quit result

运行测试.bat

@echo off&cls
cscript Test.vbs
if %errorlevel% Equ 1 Echo Process OK
if %errorlevel% Equ 2 Echo Process canceled

最新更新