开发者

Windows batch file does not wait for commands to complete

I have a batch file, which exists as soon as start it (run as admin) and does not execute commands that are in it, but if I specify it at开发者_如何学Python the command-line, it runs fine and executes all commands.

Here's what's in it:

start /wait msiexec /x SetupServices.msi /qn /l* "SetupServices.uninstall.log"

start /wait msiexec /i SetupServices.msi /qn /l* "SetupServices.install.log"


(Corrected answer)

First, if you start .exe files in a batch, it is safer, to prefix it with "call". Sometimes this is necessary to assure, that the batch is waiting to complete.

Using "start" is another possibility, but for this simple usecase not necessary.

You write that the commands are not executed. So, obviously, you have another problem, instead of the "does not wait.. to complete" problem. Taking a look of your newly provided example, this is the case. In admin mode, you have to provide a full path. With my small trick below ("%~dp0", including already backslash), you can still use the current directory in batchfiles.

Most times, if such a problem occurs with admin rights, this is a problem of the "current directory" path. A batch file with admin rights is not using it in the same way as we were used to, it does not start in it's own directory (but in System32 mostly). Not relying on the CD is an important matter of writing bullet-proof batch files.

A good example batch , combining other answers here, and solving a number of possible problems in your case is:

call msiexec /i "%~dp0MySetup.msi" /qb /L*v "%~dp0MySetup.log"
echo Returncode: %ERRORLEVEL%
pause

It uses the current directory correctly, and assumes an install commandline including a logfile (works only, if you have write access in the current directory, if not specify a path for the logfile with write access like "%TEMP%\MySetup.log".

Attention: Remember to really start the batch file with admin rights (right mouse menu or opening an admin command shell before:)


Coming back to this question I think the "correct way" to do it is via PowerShell

Start-Process -Wait -FilePath msiexec -ArgumentList /i, "setup.msi", /qn, /l*v, "install.log"   

Or just prefix it with PowerShell; to invoke directly from CMD

PowerShell; Start-Process -Wait -FilePath msiexec -ArgumentList /i, "setup.msi", /qn, /l*v, "install.log"

No hacks and no tricks :-)


Try taking the start /wait out for the msiexec lines, if that doesn't work create two more bat files one called uninstall.bat the other install.bat and use call to execute them in series.


It goes a little beyond the question, but an extension to my answer concerning handling the current directory: Here is my recommended beginning for every batch file conserving it's own path. The specialty is that it also works for UNC paths. "Pushd" automatically creates a new drive letter, if necessary (assumed, you have one free of 26). Of course you can use "popd" also at the end of the batch file instead immediately, but stable commands do not rely on the current directory as I mentioned, so it is better to always provide full paths.

@echo off
cls
pushd %~dp0
popd
set MYDIR=%CD%
echo Directory of this batch fil: %MYDIR%

You can then add the msi lines from the other answer like this:

call msiexec /i "%MYDIR%\MySetup.msi" /qb /L*v "%MYDIR%\MySetup.log"
echo Returncode: %ERRORLEVEL%
pause

(Remark: For the logfile path of course you are free, it has not to be necessarily in the same directory. But good for testing/debugging. In every case you have to have write access to the directory/file you are giving MSI with.)

While for normal MSI files it is not always necessary to start the batch with admin rights from the beginning, this technique is by far more safe (to start the MSI like already with admin rights) than too rely on the MSI UAC coming later (maybe). And it works with msiexec ... /qn too, which is important (silent installs).


Add pause statement to the end of the batch, this will prevent the console window from closing and you will be able to see error messages if any. Errors could be the reason why it exits without actually running anything. What kind of error it may be? SetupServices.msi is not found — that's what comes to my mind.


Needs the "Window Title" if you use Parameter

start /wait "Window Title" "MsiExec.exe" /i SetupServices.msi /qn /l* SetupServices.uninstall.log
start /wait "Window Title" "MsiExec.exe" /i SetupServices.msi /qn /l* SetupServices.install.log
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜