Пакетный файл Windows не ожидает завершения команд

У меня есть пакетный файл, который существует, как только он запускается (запускается от имени администратора) и не выполняет команды, которые в нем, но если я укажу его в командной строке, он работает нормально и выполняет все команды.

Вот что в этом есть:

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

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

6 ответов

Решение

(Исправленный ответ)

Во-первых, если вы запускаете.exe-файлы в пакете, то безопаснее использовать префикс "call". Иногда это необходимо для гарантии того, что партия ожидает завершения.

Использование "start" - это еще одна возможность, но для этого простого варианта использования нет необходимости.

Вы пишете, что команды не выполняются. Таким образом, очевидно, у вас есть другая проблема, а не "не ждет.., чтобы завершить" проблему. Взгляните на ваш недавно приведенный пример, это тот случай. В режиме администратора вы должны указать полный путь. С моей маленькой уловкой ниже ("%~dp0", включая уже обратную косую черту), вы все еще можете использовать текущий каталог в пакетных файлах.

В большинстве случаев, если такая проблема возникает с правами администратора, это проблема пути к "текущему каталогу". Пакетный файл с правами администратора не использует его так же, как мы привыкли, он не запускается в своем собственном каталоге (но в основном в System32). Не полагаться на компакт-диск - важный вопрос написания пуленепробиваемых пакетных файлов.

Хороший пример пакета, объединяющий здесь другие ответы и решающий ряд возможных проблем в вашем случае:

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

Он правильно использует текущий каталог и предполагает наличие командной строки установки, включающей файл журнала (работает только, если у вас есть права на запись в текущем каталоге, если не указан путь к файлу журнала с доступом для записи, например "%TEMP%\MySetup.log",

Внимание: не забудьте действительно запустить командный файл с правами администратора (правое меню мыши или открытие командной оболочки администратора раньше:)

Возвращаясь к этому вопросу, я думаю, что "правильный путь" сделать это через 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"

Нет взломов и трюков:-)

Попробуйте это так ... start / wait «Заголовок окна» «MsiExec.exe» / i SetupServices.msi /qn / l * SetupServices.uninstall.log start / wait «Заголовок окна» «MsiExec.exe» / i SetupServices.msi /qn / l * SetupServices.install.log

Насколько я помню, вам понадобится "Заголовок окна", если вы используете Параметр.

Попробуйте отключить запуск / ожидание строк msiexec, если это не сработает, создайте еще два файла bat, один из которых называется uninstall.bat, а другой - install.bat и используйте call для их последовательного выполнения.

Добавлять pause в конце пакета, это предотвратит закрытие окна консоли, и вы сможете увидеть сообщения об ошибках, если таковые имеются. Ошибки могут быть причиной, по которой он выходит, фактически ничего не запуская. Что это за ошибка? SetupServices.msi не найден - вот что приходит мне в голову.

Это выходит за рамки вопроса, но является расширением моего ответа относительно обработки текущего каталога: вот мое рекомендуемое начало для каждого пакетного файла, сохраняющего свой собственный путь. Особенность в том, что он также работает для путей 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 тоже, что важно (установка без вывода сообщений).

Другие вопросы по тегам