2017-06-05 70 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" 

可否請你是否我的評論評估是正確的。

我也很想知道爲什麼你覺得需要用不同的腳本語言來重新創建它。