我正在尝试将批处理文件转换为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脚本的当前目录?
答案 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
。但那只是我。
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
有几点:
DIM strComputer,strSCVA,strDOSBox
只是在我的MAIN PROGRAM
评论下,但这需要将它们作为参数传递给KillSvca
子例程。 taskkill
在vbscript中变得非常棘手。这看起来像是仅限vbscript的解决方案:Killing processes in Vbscript,但这个看起来更简单How to terminate a process in vbscript 答案 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"
请您评论我的评估是否正确。
我也很想知道为什么你觉得需要用不同的脚本语言重新创建它。