0

I need to create a vbs script (for maintenance purposes) that renames foo.txt to a foo.bat and launch foo.bat and when foo.bat ends, rename foo.bat again to foo.txt

This is my script vbs:

On Error Resume next
Dim Fso
Set Fso = WScript.CreateObject("Scripting.FileSystemObject")
Fso.MoveFile "foo.txt", "foo.bat"

SCRIPT = "foo.bat"
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(strPath)
strFolder = objFSO.GetParentFolderName(objFile) 

NewPath = objFSO.BuildPath(strFolder, SCRIPT)
set objshell = createobject("wscript.shell")
objshell.Run NewPath, vbHide, true

Fso.MoveFile "foo.bat", "foo.txt"

On Error GoTo 0

the script executes well. Rename foo.txt to foo.bat. Launches foo.bat, but does not expect foo.bat to end and renames it to foo.txt.

I changed this line, nothing happens:

objshell.Run NewPath, vbHide, 1, true

What do I need or what did I do wrong?

Alternative Solution (no VBScript): (By suggestion of @KenWhite)

code:

On Error Resume next
Dim Fso
Set Fso = WScript.CreateObject("Scripting.FileSystemObject")
Fso.MoveFile "foo.txt", "foo.bat"

SCRIPT = "foo.bat"
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(strPath)
strFolder = objFSO.GetParentFolderName(objFile) 

NewPath = objFSO.BuildPath(strFolder, SCRIPT)
set objshell = createobject("wscript.shell")
objshell.Run NewPath, true

On Error GoTo 0

And at the end of foo.bat:

ren foo.bat foo.txt
exit

Thanks

acgbox
  • 312
  • 2
  • 13
  • Why use VBScript at the end at all? Have the last line of the batch file rename the batch file back to .txt. – Ken White Feb 23 '19 at 00:45
  • That can not be done because the batch file is running. foo.bat can not rename itself – acgbox Feb 23 '19 at 00:46
  • You're wrong. Foo.bat can indeed rename itself. It can also delete itself. Did you try it? – Ken White Feb 23 '19 at 00:49
  • yes. with command ren foo.bat foo.txt at the end of foo.bat – acgbox Feb 23 '19 at 00:57
  • Which works just fine. I've done it many times without an issue. In fact, I just tested it on Windows 10 64 bit, and it worked perfectly fine. Ignore the *batch file not found* error - foo.txt is in the folder, and foo.bat is not. – Ken White Feb 23 '19 at 01:11
  • It should wait for the bat to finish. I wouldn't think you would need to use cmd /c with the execution of the batch file but give it a try. – Squashman Feb 23 '19 at 01:27
  • @KenWhite You are right. The command works inside foo.bat. The problem is in the vbs, that "vbHide" was causing foo.bat not to run correctly. If you want you can put the correct answer to select it – acgbox Feb 23 '19 at 01:28
  • Thank you, but I didn't answer the question you asked. I just offered an alternate way to solve the problem. :-) – Ken White Feb 23 '19 at 01:31
  • 1
    @KenWhite As you wish. Anyway, I thank you very much for your alternative proposal. It worked. – acgbox Feb 23 '19 at 01:37
  • Just in case it bothers you, you can remove the error message using redirection, by using. `ren foo.bat foo.txt 2>1>nul` – Ken White Feb 23 '19 at 03:01

1 Answers1

1

Here is a possible solution just in case anyone is wondering how to solve this problem without resorting to the alternate proposal mentioned above.

Dim Fso
Set Fso = WScript.CreateObject("Scripting.FileSystemObject")
Fso.MoveFile "foo.txt", "foo.bat"

SCRIPT = "foo.bat"
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(strPath)
strFolder = objFSO.GetParentFolderName(objFile) 

NewPath = objFSO.BuildPath(strFolder, SCRIPT)
set objshell = createobject("wscript.shell")

objshell.Run "%COMSPEC% /c " & NewPath, 1, true

' Changes start here
'===================================================================

strComputer = "."

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

' Hold execution until cmd.exe process is done
do 
    ' Get cmd.exe processes
    Set colProcessList = objWMIService.ExecQuery _
    ("Select Name from Win32_Process WHERE Name LIKE 'cmd.exe'")
    WScript.Sleep 250
Loop while colProcessList.count > 0

Fso.MoveFile "foo.bat", "foo.txt"
  • No offense, but I think adding one line tot he end of the batch file so that it renames itself is much easier. :-) – Ken White Feb 23 '19 at 03:07
  • Yes, I agree. I never said that adding one line to the end of the batch file wasn't the "easier solution". This question is tagged as "vbscript", under the title of "rename a file using VBSCRIPT...", so it's only natural for it to have a VBScript solution for the sake of consistency. –  Feb 23 '19 at 03:59
  • I agree, which is why I turned down the poster's suggestion that I post my solution as an answer - it wasn't VBScript. – Ken White Feb 23 '19 at 04:01
  • On a side note, I have to say that, although the changes I proposed ensure that execution will continue only after all cmd.exe processes are terminated, the initial code presented by the poster did wait the conclusion of a dummy bat script before renaming it back to .txt during the tests conducted on my personal machine. –  Feb 23 '19 at 04:53
  • @WesternSage Thanks. Your script works. PD: This line is wrong: objshell.Run "%COMSPEC% /c " & NewPath, 1, true. Must be: objshell.Run NewPath, true (because show windows cmd foo.bat running) – acgbox Feb 23 '19 at 23:54
  • It seems you might benefit from a look at the docs of the Wscript.Shell Run function: https://ss64.com/vb/run.html –  Feb 24 '19 at 01:02
  • 1
    You'll see it has the following general form "objShell.Run (strCommand, [intWindowStyle], [bWaitOnReturn])", so the window was showing because I set the parameter "intWindowStyle" to 1 while I was testing, not because of the "%COMSPEC% /c" construct, all it does is to execute a command and terminate the shell (as oposed to %COMSPEC% /k, which would would not terminate the shell after the command). So, if you want the window not to show, just use objshell.Run "%COMSPEC% /c " & NewPath, 0, true. –  Feb 24 '19 at 01:08
  • @WesternSage new similar to this one https://stackoverflow.com/questions/54874471/how-to-run-more-than-one-batch-with-vbs-and-set-batch-file-path-using-environmen – acgbox Feb 25 '19 at 20:52