完成批/注销或关机vbs脚本

问题描述:

现状:完成批/注销或关机vbs脚本

为了保持它的简单:我得到了启动连接到虚拟机的控制台应用程序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时,它强制关闭脚本,并且不会继续脚本以删除日志文件。这会导致日志不相关,因为某些注销或强制关闭脚本的用户仍然存在于日志文件中,就像虚拟机仍在使用中一样。

问题:

“开始/等待”等待直到应用程序被关闭,但是当用户关闭窗口或注销脚本是力封闭,不会继续。

问:

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

最佳选择不是检查文件是否存在,而是锁定文件。如果文件被锁定,它正在使用中。如果未锁定,则说明您的方案是使用旧连接的锁定文件描述的。从两个控制台启动以下代码以查看其工作原理。

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

使用流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 
+0

看起来坚实,工作良好,我从来没有使用过输出蒸汽,但我会尝试实现这个到我的脚本。 – lalilaloe