2017-06-05 71 views
1

我想将批处理文件转换为VBS。这是我迄今为止所拥有的。寻找适当格式的建议,以及有关此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中正确启动一个程序。我用google搜索了这个,但是我不明白这个实现,如果有人能够告诉我它是如何在我自己的代码中工作的话,这将会有所帮助。另外,VBS中cd“%〜dp0 ../”的等效值是多少?换句话说,相当于将工作目录相对设置为VBS脚本的当前目录?

+0

我认为这可能是我在这里看到的第一个“我该如何转换这个代码”的问题,实际上就是_good_。 – SomethingDark

+0

另外,我看到两个子声明,但没有'end sub's。无可否认,我唯一的VB *体验是使用VBA,但我确定你需要这些。 – SomethingDark

回答

2

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

它看起来像批处理文件工作正常 - 你为什么要改变它为VBScript?

好吧,够了。

当我写vbscript的时候,我会把子程序放在顶部,而主逻辑放在最下面。我不确定这是每个人都做的,但它意味着我可以扫描该程序,请参阅FUNCTION isProcessRunning,了解这十几行,然后继续。这意味着,当我到达所谓的部分时,我已经明白了它的作用,以及它大概会做什么。

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

例如我有一个listmounts.bat这基本上是:

cscript %~dp0\listmounts.vbs 

我这样做,因为我做很多东西的外壳,像这样,启动它,我只需键入listmounts运行它,而不是cscript \path\to\listmounts.vbs。但那只是我。

Call in vbscript在批处理文件中与goto的工作方式非常不同。 Call希望调用子程序或函数(如IsProcessRunning)并到达该子程序的末尾,然后返回到从其调用的位置。这显然不是goto在批处理文件中的工作方式。每次你做call它使用一些内存管理你从哪里调用,当它返回时,它回收该内存。因此,随着你设置的内容,随着调用的交叉,如果运行时间足够长,你最终可能会耗尽内存。可能需要一段时间。

所以这里是我如何构造它。你必须调整它才能使它工作(部分原因是我的机器上没有svca或dosbox,部分原因是我运行的是Linux ATM,根本无法测试它)。

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 

几个要点:

  • 我假定你isProcessRunning功能工作。我没有把它弄糟。
  • 理想情况下,我会DIM strComputer,strSCVA,strDOSBox正好在我的MAIN PROGRAM评论下,但这需要将它们作为参数传递给KillSvca子例程。
  • taskkill在vbscript中变得非常复杂。这看起来像一个VBScript唯一的解决办法:Killing processes in Vbscript,但这个看起来简单的How to terminate a process in vbscript
  • 启动您的应用程序是一个有点棘手了,但是这里有一个建议:Launch programs whose path contains spaces
+0

谢谢!而不是使用Call KillScva,我只是把“KillScva”,它会起作用吗?换句话说,就是放弃“通话”部分? 此外,批处理文件确实很好。但是,我有一个难以解释的问题。我可以做一个简短的视频来详细说明这个问题,因为我认为解释这种方式比通过文本更容易,特别是当你看到它发生的时候。如果我这样做,我会再次回复。 也许问题可以通过另一种方式解决,而无需将我的批处理文件转换为VBS。 该批处理文件的格式是否正确? – Lucas

+0

是的,我认为'call'是不必要的,看看我在这里的listmounts.vbs文件中有一个'sub'。 – GregHNZ

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" 

可否请你是否我的评论评估是正确的。

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