【问题标题】:Finish batch/vbs script on logoff or shutdown在注销或关机时完成批处理/vbs 脚本
【发布时间】:2013-12-19 10:15:30
【问题描述】:

情况:

为了简单起见:我在一个网络共享上获得了多个快捷方式,这些快捷方式启动了一个连接到虚拟机控制台的 VMwareclient 应用程序。快捷方式如下所示:

\\share\vmware-vmrc.exe -h HOST -u USER -p PASS "[LocalStorage] NAME/NAME.vmx"

但我想知道是否有人已经在使用此控制台连接,因此我可以避免启动此快捷方式并选择另一台机器。所以我制作了一个脚本来执行此操作并将快捷方式更改为:

C:\Windows\System32\wscript.exe \\share\start.vbs NAME "[LocalStorage] NAME/NAME.vmx"

这会打开一个以静默方式运行批处理文件的 vbscript,因此用户看不到它。

arg = " " & WScript.Arguments.UnNamed(0) & " """ & WScript.Arguments.UnNamed(1) & """"
CreateObject("Wscript.Shell").Run "client.cmd" & arg ,0,False

这将打开运行 VMwareclient 启动并连接到给定虚拟机的 client.cmd,并写入日志文件以记录哪个用户正在使用虚拟机。

@echo off
pushd "%~dp0"
set TIMESTAMP=%TIME:~0,2%:%TIME:~3,2%
set CLIENT=%1

:start
IF EXIST logs\%client% goto msg
echo %username% since %TIMESTAMP% on %DATE% >logs\%client%
start /wait c:\vmwareclient\vmware-vmrc.exe -h HOST -u USER -p PASS %2
del logs\%client%
goto exit

:msg
for /f "delims=" %%x in ('type logs\%client%') do set "type=%%x"
echo wscript.quit MsgBox ("%client% is in use by %type%. Do you like to continue?", 4, "%client% is in use") > yesno.vbs
wscript //nologo yesno.vbs
set value=%errorlevel%
del yesno.vbs
if "%value%"=="6" start /wait c:\vmwareclient\vmware-vmrc.exe -h HOST -u USER -p PASS %2
if "%value%"=="7" goto exit
goto exit

:exit
popd

变量 %client% 包含快捷方式中给出的第一个参数,它代表 NAME。

这一切都很好。但是有一个问题,在“start /wait :..”处,脚本一直等到客户端应用程序关闭。但是,当用户注销或关闭 Windows 时,它会强制关闭脚本,并且不会继续执行脚本来删除日志文件。这会导致日志无关紧要,因为一些注销或强制关闭脚本的用户仍然存在于日志文件中,就好像虚拟机仍在使用中一样。

问题:

“start /wait”等到应用程序关闭,但当用户关闭窗口或注销时,脚本会被强制关闭并且不会继续。

问题:

是否有解决方案可以批量检测这种力关闭? (可能不是) 我需要切换到 VBscript 或其他程序/脚本语言来完成此操作吗?

【问题讨论】:

    标签: vb.net windows batch-file vbscript forceclose


    【解决方案1】:

    最好的选择不是检查文件是否存在,而是锁定文件。如果文件被锁定,则它正在使用中。如果它未锁定,则您处于使用来自旧连接的锁定文件描述的场景中。从两个控制台启动以下代码,看看它是如何工作的。

    它的作用是将流 3 的输出(0=stdin 1=stdout 2=stderr 3-9= 供您使用)重定向到锁/日志文件。当括号块中的代码运行时,此填充将锁定(已写入)。尝试运行的批处理文件的其他实例将不允许打开锁定文件进行写入,因此不会执行该块。这种情况是通过在块内分配了一个值的环境变量来检查的。如果有值,则执行该块,如果没有值(未定义),则该块尚未执行(日志文件被另一个进程锁定)。

    Stream 3 用于代替通常的输出重定向,以允许块内的代码将信息回显到控制台,但这不是必需的。

    @echo off
        rem Prepare environment
        setlocal enableextensions
    
        rem The file used as flag   
        set "file=client.log"
    
        rem The variable used to test if we got the lock
        set "started="
    
        ((
            rem Mark the process as started
            set "started=yes"
    
            rem echo data to screen
            echo User %username% will hold the lock
    
            rem save data to log file. It will be on output stream 3
            echo %username% >&3
    
            rem Simulate the process to work
            pause >nul
    
            rem Redirect output stream 3 to our lock/log file
            rem Send stderr to nul to not show errors (ex. file lock fail)
        ) 3> "%file%" ) 2>nul
    
        rem Check if the process got the lock and has ended
        rem OR it couldn't get the lock
        if not defined started (
            <"%file%" set /p "lockedBy="
            setlocal enabledelayedexpansion
            echo(Process is locked by !lockedBy!
            endlocal
        )
    
        endlocal
    

    【讨论】:

    • 看起来不错,效果很好,我以前从未使用过输出流,但我会尝试在我的脚本中实现它。
    猜你喜欢
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多