VBscript wscript.shell execute not refreshing in winpe

1.5k views Asked by At

I have a DISM based imaging solution for use in WinPE as follows:

set WshShell = CreateObject("WScript.Shell")

Wscript.StdOut.WriteLine "[44m[1;37m restoring image boot partition for " & name & " [0m[40m"  

Set objExec = WshShell.Exec("DISM.exe /Apply-Image /ImageFile:" & name & "/index:1 /ApplyDir:c:\")

Do
    line = objExec.StdOut.ReadLine()
    Wscript.StdOut.WriteLine line
Loop While Not objExec.Stdout.atEndOfStream

There are two issues with the way this executes:

  1. The execution seems to stall and I have to press enter for it to continue.
  2. The second problem is that the progress bar does not show up. It stays at "applying image".

Normally, if you execute DISM.exe /Apply-Image /ImageFile:" & name & "/index:1 /ApplyDir:c:\ it will look something like this:

"applying Image {1%-------------------------------------}

Interestingly this segment which prepares the disk shows each line of execution:

Set WshShell = CreateObject("WScript.Shell")
Set objExec = WshShell.Exec("diskpart.exe /s clean.sh")
Do
    line = objExec.StdOut.ReadLine()
    Wscript.StdOut.WriteLine line
Loop While Not objExec.Stdout.atEndOfStream

I think the DISM output is different because it only has one line that refreshes itself, but I'm not sure how to code around it.

1

There are 1 answers

0
MC ND On

I don't know how dism.exe outputs data (at the moment i only have a XP to test) but there is at least two cases in which code as

Set objExec = objShell.Exec( ...... )
Do
    WScript.StdOut.WriteLine(objExec.StdOut.ReadLine())
Loop While Not objExec.Stdout.atEndOfStream

will not work as expected.

One is when the program output is directly send to the console buffer, not writing into stdout. As the code reads from the stdout stream of child process and there is no anything on it....

Second is when there is no end of line mark in child process output. Both Read and ReadLine return when the Enter key is pressed or when a CRLF is inside content being read. But, the tipical form of generating a progress bar in a console output is not sending the LF part, sending only the CR to return the caret to the start of the line and output the next change in progress bar just writing over the first drawn one. In this case, both the indicated methods will not return until there is a CRLF included in the output stream of the child process or the stream is closed.

As said, i've no access to DISM to test, but it seems it will fall in one of the two cases.

And no, it seems Run method has no way to run the command in the same window.

If the "same window" is a mandatory requirement, the better approach is to code something like

  • start a "master" batch file
  • this batch file starts the vbs
  • the vbs do what it needs to do and in the case of having to execute DISM or anything similar, generate a temporary batch file with the adecuate content and exit from vbs
  • the "master" batch file retrieves the control, checks for the presence of the temporary batch file and calls it
  • on completion of the temporary batch file, "master" retrieves the control and starts again the vbs
  • use the method that better adapts (arguments, environment variables, flag files, ...) to determine that this is not the first execution and continue execution as required.