需要帮助使此批次转换为VBS才能正常工作

时间:2017-06-05 03:23:36

标签: batch-file vbscript

我正在尝试将批处理文件转换为VBS。这就是我到目前为止所拥有的。寻找有关正确格式化的建议,以及有关此VBS脚本目前无法正常工作的任何帮助。这是我到目前为止所得到的:

OPTION EXPLICIT
DIM strComputer,strSCVA,strDOSBox

strComputer = "." ' local computer
strSCVA = "scva.exe"
strDOSBox = "dosbox.exe"

' Check if scva.exe is running at startup (. = local computer)
IF isProcessRunning(strComputer,strSCVA) THEN
    Call LoopStart
ELSE
    cd "%~dp0../"
    start /min "" "scva.exe"
    Call LoopStart
END IF

Sub LoopStart
' Exits script if scva.exe is manually terminated, otherwise, calls CheckDOSBox
IF isProcessRunning(strComputer,strSCVA) THEN
    Call CheckDOSBox
ELSE
    WScript.Quit
END IF

Sub CheckDOSBox
' Goes to LoopStart while dosbox.exe is running, otherwise, calls Kill
IF isProcessRunning(strComputer,strDOSBox) THEN
    Call LoopStart
ELSE
    Call Kill
END IF

Sub Kill
' Sends command to terminate scva.exe while scva.exe is running, otherwise, exits script
IF isProcessRunning(strComputer,strSCVA) THEN
    taskkill /IM scva.exe
    Call Kill
ELSE
    WScript.Quit
END IF

' Function to check if a process is running
FUNCTION isProcessRunning(BYVAL strComputer,BYVAL strProcessName)

    DIM objWMIService, strWMIQuery

    strWMIQuery = "Select * from Win32_Process where name like '" & strProcessName & "'"

    SET objWMIService = GETOBJECT("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" _ 
            & strComputer & "\root\cimv2") 


    IF objWMIService.ExecQuery(strWMIQuery).Count > 0 THEN
        isProcessRunning = TRUE
    ELSE
        isProcessRunning = FALSE
    END IF

END FUNCTION

以下是转换的原始批处理文件(我也写过):

REM Runs scva.exe if it is not running; kills process after dosbox.exe is terminated

tasklist /FI "IMAGENAME eq scva.exe" 2>NUL | find /I /N "scva.exe">NUL
if "%ERRORLEVEL%"=="0" (
    goto LoopStart
) else (
    cd "%~dp0../"
    start /min "" "scva.exe"
    goto LoopStart
)

:LoopStart
REM Exits script if scva.exe is manually terminated, otherwise, goes to CheckDOSBox

tasklist /FI "IMAGENAME eq scva.exe" 2>NUL | find /I /N "scva.exe">NUL
if "%ERRORLEVEL%"=="0" (
    goto CheckDOSBox
) else (
    exit
)

:CheckDOSBox
REM Goes to LoopStart while dosbox.exe is running, otherwise, goes to Kill

tasklist /FI "IMAGENAME eq dosbox.exe" 2>NUL | find /I /N "dosbox.exe">NUL
if "%ERRORLEVEL%"=="0" (
    goto LoopStart
) else (
    goto Kill
)

:Kill
REM Sends command to terminate scva.exe while scva.exe is running, otherwise, exits script

tasklist /FI "IMAGENAME eq scva.exe" 2>NUL | find /I /N "scva.exe">NUL
if "%ERRORLEVEL%"=="0" (
    taskkill /IM scva.exe
    goto Kill
)
exit

我认为我的问题领域不知道如何在VBS中正确启动程序。我用谷歌搜索了这个,但我不了解实现,如果有人能告诉我它在我自己的代码中是如何工作的话会有所帮助。另外,相当于cd"%~dp0 ../"在VBS?换句话说,相当于将工作目录相对设置为VBS脚本的当前目录?

2 个答案:

答案 0 :(得分:2)

我想我会首先发布我的预订,然后看看我是否真的可以提供帮助。

看起来批处理文件工作正常 - 为什么要将其更改为vbscript?

好的,够了。

当我编写vbscript时,我将子程序放在顶部,主要逻辑放在底部。我不确定这是不是每个人都做了什么,但这意味着我可以扫描程序,看FUNCTION isProcessRunning,了解那十几行,然后继续。这意味着,当我到达其所称的部分时,我已经理解了它的用途,并且大致了解它的作用。

我遇到的cd与vbscript最接近的是WScript.CurrentDirectory属性。 http://www.vbsedit.com/html/a36f684c-efef-4069-9102-21b3d1d55e9e.asp就个人而言,我不倾向于使用它,因为我通常会编写一个批处理文件来启动我的vb脚本,如果有必要,我会在那里找到正确的地方。

e.g。我有listmounts.bat基本上是:

cscript %~dp0\listmounts.vbs 

我之所以这样做是因为我在shell中做了很多东西,并且像这样,要启动它,我只需输入listmounts来运行它,而不是cscript \path\to\listmounts.vbs。但那只是我。

vbscript中的

Call与批处理文件中的goto非常不同。 Call期望调用子例程或函数(如IsProcessRunning)并到达该子例程的末尾,然后返回到调用它的位置。这显然不是goto在批处理文件中的工作方式。每次执行call时,它会占用一些内存来管理您调用的位置,当它返回时,它会回收该内存。因此,对于您已设置的内容,通过调用交叉,如果运行时间足够长,您最终可能会耗尽内存。可能需要一段时间。

所以这就是我如何构建它。您必须对其进行调整以使其正常工作(部分原因是我的机器上既没有svca或dosbox,部分原因是因为我正在运行Linux ATM并且根本无法对其进行测试)。 / p>

OPTION EXPLICIT
DIM strComputer,strSCVA,strDOSBox


' start scva if it's not already running.  Kill it if dosbox dies.
' Author: Lucas 5 June 2017


' Function to check if a process is running
FUNCTION isProcessRunning(BYVAL strComputer,BYVAL strProcessName)

    DIM objWMIService, strWMIQuery

    strWMIQuery = "Select * from Win32_Process where name like '" & strProcessName & "'"

    SET objWMIService = GETOBJECT("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" _ 
            & strComputer & "\root\cimv2") 


    IF objWMIService.ExecQuery(strWMIQuery).Count > 0 THEN
        isProcessRunning = TRUE
    ELSE
        isProcessRunning = FALSE
    END IF

END FUNCTION


' kill the svca executable.
SUB KillSvca() 

    ' Keep trying to kill scva until it actually has exited.
    WHILE isProcessRunning(strComputer,strSCVA) 
        ' this won't actually work - see below for an alternative
        taskkill /IM scva.exe
    WEND
END SUB     

' ------  MAIN PROGRAM ----    


strComputer = "." ' local computer
strSCVA = "scva.exe"
strDOSBox = "dosbox.exe"

' Start SCVA if it's not already running.

IF NOT isProcessRunning(strComputer,strSCVA) THEN
    ' As above, I'd make sure it's in the correct folder first
    cd "%~dp0../"
    ' And this won't work either. see below.
    start /min "" "scva.exe"
END IF

WHILE isProcessRunning (strComputer, strSCVA) 

    IF NOT isProcessRunning(strComputer,strDOSBox) THEN
        KIllScva
    END IF

WEND

有几点:

答案 1 :(得分:1)

这不能回答你的问题,它是一个重写的批处理文件,希望能够复制我对你想要你的vbscript做什么的评估:

@Echo Off
Set "_=0"
TaskList /FI "IMAGENAME eq dosbox.exe" 2>Nul|Find /I "dosbox.exe">Nul&&Set/A _+=1
TaskList /FI "IMAGENAME eq scva.exe" 2>Nul|Find /I "scva.exe">Nul&&Set/A _+=2

If %_% Equ 3 Exit/B

If %_% Equ 2 TaskKill /IM "scva.exe"&&Set/A _-=2

If %_% Equ 0 Start "" "DOSBox.exe"&&Set/A _+=1

If %_% Equ 1 Start "" /D "%~dp0.." /MIN "scva.exe"

请您评论我的评估是否正确。

我也很想知道为什么你觉得需要用不同的脚本语言重新创建它。