Windows 批处理文件不等待命令完成

发布于 2024-11-28 02:47:10 字数 274 浏览 3 评论 0原文

我有一个批处理文件,该文件一启动(以管理员身份运行)就存在,并且不执行其中的命令,但如果我在命令行指定它,它会正常运行并执行所有命令。

这是其中的内容:

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

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

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 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"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

情感失落者 2024-12-05 02:47:10

回到这个问题,我认为“正确的方法”是通过 PowerShell

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

或者只是在其前面加上 PowerShell; 来直接从 CMD 调用

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

,没有黑客也没有技巧:-)

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 :-)

夏天碎花小短裙 2024-12-05 02:47:10

(正确答案)

首先,如果批量启动.exe文件,在其前面加上“call”前缀会更安全。
有时,这对于确保批次正在等待完成是必要的。

使用“start”是另一种可能性,但对于这个简单的用例来说没有必要。

您写道这些命令执行。所以,显然,你有另一个问题,而不是“不等待..完成”问题。
看看你新提供的例子,就是这种情况。在管理模式下,您必须提供完整路径。通过我下面的小技巧(“%~dp0”,包括已经的反斜杠),您仍然可以在批处理文件中使用当前目录。

大多数时候,如果管理员权限出现这样的问题,这是“当前目录”路径的问题。具有管理员权限的批处理文件的使用方式与我们习惯的方式不同,它不会在自己的目录中启动(但主要在 System32 中)。不依赖 CD 是编写防弹批处理文件的一个重要问题。

一个很好的示例批处理,在这里结合其他答案,并解决您的情况中的许多可能的问题是:

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

它正确使用当前目录,并假设安装命令行包括日志文件(仅当您在当前目录中具有写访问权限时才有效) ,如果没有指定具有写访问权限的日志文件的路径,例如“%TEMP%\MySetup.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:)

笑脸一如从前 2024-12-05 02:47:10

尝试将 msiexec 行的 start /wait 取出,如果这不起作用,请再创建两个 bat 文件,一个名为 uninstall.bat,另一个名为 install.bat,并使用 call 依次执行它们。

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.

孤蝉 2024-12-05 02:47:10

它有点超出了问题的范围,而是我关于处理当前目录的答案的扩展:这是我建议的每个批处理文件的开头,保存其自己的路径。特殊之处在于它也适用于 UNC 路径。如果需要,“Pushd”会自动创建一个新的驱动器号(假设您有 26 个驱动器号)。当然,您也可以在批处理文件的末尾使用“popd”,而不是立即使用,但正如我提到的,稳定的命令不依赖于当前目录,因此最好始终提供完整路径。

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

然后,您可以添加其他答案中的 msi 行,如下所示:(

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

备注:对于日志文件路径,当然您是自由的,它不一定位于同一目录中。但有利于测试/调试。在每种情况下,您都有对您提供 MSI 的目录/文件具有写访问权限。)

虽然对于普通 MSI 文件,并不总是需要从一开始就以管理员权限启动批处理,但这种技术到目前为止更安全(像这样启动 MSI)已经拥有管理员权限)而不是太依赖MSI UAC 稍后推出(也许)。
它也可以与 msiexec ... /qn 一起使用,这很重要(静默安装)。

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).

乞讨 2024-12-05 02:47:10

如果您使用参数,则需要“窗口标题”

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

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
烂人 2024-12-05 02:47:10

pause 语句添加到批处理末尾,这将阻止控制台窗口关闭,并且您将能够看到错误消息(如果有)。错误可能是它在没有实际运行任何内容的情况下退出的原因。可能是什么类型的错误?找不到SetupServices.msi——这就是我的想法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文