RoboCopy.exe не работает в скрипте Powershell - PullRequest
1 голос
/ 16 февраля 2020

Я постараюсь сделать этот вопрос очень простым. Если я запускаю следующее, оно работает без проблем:

$localData = "C:\"
$netData = "\\OtherPC\shared\"
Start-Process "RoboCopy.exe" -argumentlist " `"$localData`" `"$netData`" "

Однако, как только я добавляю какие-либо переключатели (см. Ниже), он не работает. Ошибок не видно.

$localData = "C:\"
$netData = "\\OtherPC\shared\"
Start-Process "RoboCopy.exe" -argumentlist " `"$localData`" `"$netData`" /copyall"

Попытка исправить это была реальная боль, любая помощь приветствуется.

РЕДАКТИРОВАТЬ: Исправлено, и вот окончательный рабочий синтаксис:

$localFiles = "C:\Users\"
$netFiles = "\\netLocation\migration\Users\"

Start-Process "RoboCopy.exe" -NoNewWindow -argumentlist " `"$localFiles\`" `"$netFiles\`" /s /r:1 /w:5 /mt:16"

1 Ответ

1 голос
/ 16 февраля 2020

Как отступление: вы можете использовать Start-Process намеренно для выполнения длительной операции асинхронно в новом окне , но более типичным случаем является выполнять консольные приложения, такие как Robocopy.exe синхронно , в том же окне , и в этом случае вам необходимо вызвать их напрямую (c:\path\to\some.exe ... или & $exePath ... ) - см. этот ответ . Альтернативой асинхронному выполнению в новом окне является использование фонового задания .

Вам необходимо double в конце \ in Ваши аргументы пути, если они (в конечном итоге) заключены в "..." в командной строке (в конечном итоге), представлены:

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

$localData = 'C:\\'
$netData = '\\OtherPC\shared\\'

Другое решение (на Windows) для путей к файлам , в частности, заключается в вставке пробела между конечным \ и ". Это работает, потому что вызовы файловой системы WinAPI игнорируют завершающие пробелы в путях.

Причина, по которой \\ требуется в конце, состоит в том, что RoboCopy.exe (и, фактически, фактически все внешние программы) интерпретируют последовательность \" как экранированный " символ вместо того, чтобы использовать дословно вместо syntacti c function.

Если вам нужно добавить дополнительные \ программно , используйте следующее:

$localDataEscaped = $localData -replace '\\$', '\\'
$netDataEscaped = $netData -replace '\\$', '\\'

Подсказка по отладке для Start-Process звонков :

(Временно) добавляет -NoNewWindow -Wait к вызову, в результате чего вывод команды появляется в том же окне , что дает вам возможность осмотреть это; по умолчанию Start-Process запускает команду в новом окне (на Windows), в котором автоматически закрывает после завершения команды, потенциально не давая вам достаточно времени, чтобы просмотреть вывод.

...