Возможно ли получить `errorlevel 1` из` xcopy` в Windows 10?

1253
MC ND

Документация Microsoft гласит, что xcopyкоды выхода

Exit code Description 0 Files were copied without error. 1 No files were found to copy. 2 The user pressed CTRL+C to terminate xcopy. 4 Initialization error occurred.  There is not enough memory or disk space,  or you entered an invalid drive name  or invalid syntax on the command line. 5 Disk write error occurred. 

Я бегу Windows 10 64 - битной системы (испанский локали), и я попробовал все, что я мог придумать, чтобы получить errorlevel 1от xcopy, но я не смог. И под всем, что я имею в виду, единственное, что я не проверял, было /Nс длинными именами файлов в источнике, где короткие имена не включены (в моей среде я не могу это проверить). Подозрительный не являющаяся соответсвующая символы, не являющиеся настоящие имена файлов, пустые папки, /D, /EXCLUDE, /A, /M, /U, ... были испытаны.

Я, хотя это должно быть легко (не файлы найдены ?, легко), но я был неправ, это не так, поэтому я отладил, xcopy.exeи вот что я увидел:

  • xcopyвнутренне использует метод, который вызывается DisplayMessageAndExit(messageID, WSTRING, exitCode)для отображения сообщения и выхода. Он также использует несколько exitвызовов, чтобы выйти из программы в некоторых случаях (например Ctrl-C)

  • Я не нашел ни одного exitвызова, который мог бы использовать значение1

  • Из списка сделанных вызовов DisplayMessageAndExitни один из них не передает / получает значение в 1качестве кода выхода.

  • Из списка вызовов, сделанных DisplayMessageAndExitтолько для одного из них, используйте MessageID 0x5622(в моей установке связанные ресурсы находятся в C:\Windows\System32\es-ES\ulib.dll.muiзависимости от локали), то есть No se encuentra el archivo: %1( File not found - %1), и код выхода, используемый в вызове:4

Может быть, есть способ xcopyгенерировать 1код выхода, но я не знаю как.

Таким образом, вопрос: есть ли способ получить errorlevel 1код выхода xcopy? Что мне не хватает?

4
Я ожидаю, что если вы используете `/ d` и файлы не новее. AFH 7 лет назад 0
@AFH Нет. `/ d` не делает этого. DavidPostill 7 лет назад 0
@DavidPostill - Извините, у меня не было времени проверить. Я сказал, что ожидаю этого, и я чувствую, что должен. AFH 7 лет назад 0
@AFH Вы правы, он должен (он возвращает `0`). Я пробовал `xcopy foo bar`, где` foo` не существует, и он тоже этого не делал (он возвращает `4`). DavidPostill 7 лет назад 0
@ DavidPostill, как я вижу, есть два варианта: это невозможно или это так очевидно, что я этого не вижу. Но все что я хоть как очевидное не сработало. MC ND 7 лет назад 0
@DavidPostill - единственные другие возможности, о которых я могу подумать, которые должны возвращать 1, - это копирование пустого каталога или использование маски файла, не имеющей совпадений. AFH 7 лет назад 0
@MCND - Как и вы, я перепробовал все, что мог придумать, не найдя ничего, что возвращает 1. Это очень похоже на давнюю ошибку. Лучшее, что вы можете сделать, это `xcopy ...>% temp% \ xcopy.tmp`; если код возврата равен 0, используйте `findstr / l" 0 Скопировано файлов "<% temp% \ xcopy.tmp`, чтобы проверить, не скопированы ли файлы. Не поддавайтесь соблазну на что-либо: например, передача по `tee` даст код возврата, установленный` tee`, а не из `xcopy`. AFH 7 лет назад 0
@AFH, после тестирования я был уверен на 80%, что это ошибка. После отладки `xcopy` я был на 99,9% уверен, что это ошибка, но я мог пропустить что-то, что кто-то другой знает. Да, я знаю, как обрабатывать `0 File (s)` и поведение канала, но в этом случае меня интересует только поведение кода выхода. В любом случае, спасибо за ваше тестирование. MC ND 7 лет назад 0
Я думаю, что они в Microsoft _know_ это. Существует пример `COPYIT.BAT` по предоставленной ссылке _to execute_` xcopy` _operations и используется команда batch_ `if` _ для обработки кода выхода в случае возникновения ошибки_. Пакет вообще не заботится о `errorlevel 1` и обрабатывает только уровни ошибок 4, 2 и 0 (_ это не ошибка, это особенность_?) JosefZ 7 лет назад 2
@JosefZ, спасибо, я пропустил командный файл (рендеринг в одну строку не помогает). Кажется, * кто пишет это, на самом деле не знает, как работает `errorlevel`. `if errorlevel 0` всегда имеет значение true для любого неотрицательного значения errorlevel, а` xcopy` не документирует отрицательные значения. Кажется, что * намерение состоит в том, чтобы использовать переход к следующей метке для обработки случая `errorlevel 1`, но, как уже было сказано, код неправильный. MC ND 7 лет назад 0
Я уверен, что `if errorlevel 0 goto exit` предназначен для пропуска следующей метки`: lowmemory` (обратите внимание на `if errorlevel 4 goto lowmemory`. Errorlevel правильно проверяется в порядке убывания. Отсутствует проверка` if errorlevel 1` больше интересная вещь для меня с точки зрения вашего вопроса. JosefZ 7 лет назад 0
@JosefZ, чтобы пропустить `: lowmemory`, вам нужен только` goto`, а не `if errorlevel 0`, что в этом сценарии всегда верно. Зачем использовать `если`? Это всего лишь мое мнение, но для меня это (неправильный) прорыв, как в выражении C `switch`. Конечно, я не знаю * «почему» * и могу ошибаться (опять же). В любом случае, да, ваша точка зрения создает подозрительное упущение в их коде. MC ND 7 лет назад 2

2 ответа на вопрос

0
WeaponGod243

Чтобы получить errorlevel1, единственное, что я думаю, вы можете сделать, это иметь источник файла, которого там нет.

Как указано, это было проверено, и нет, он не будет генерировать `errorlevel 1` MC ND 6 лет назад 0
попробуйте этот сайт: https://ss64.com/nt/ WeaponGod243 6 лет назад 0
0
BeowulfNode42

Единственное, о чем я могу думать, это какое-то условие гонки: когда xcopy собирает список файлов, которые он будет копировать, и фактически делает копию, какой-то другой процесс удаляет или перемещает файлы.

Если вы можете получить ошибку 1, если отсутствуют только НЕКОТОРЫЕ из исходных файлов, то это может быть сделано специально. Единственный способ сделать это специально - это запустить 2 или более отдельных процесса, одну команду xcopy и одну команду удаления или перемещения, и все они будут работать с одними и теми же исходными файлами. Вам понадобится источник с большим количеством файлов, чтобы дать конкурирующим процессам время обогнать друг друга.

  1. Запустите команду move, del или robocopy / mov для папки с большим количеством файлов.
  2. в другом окне и задолго до того, как первая команда завершится, запустите команду xcopy

Пропуск ключа / C может означать, что если это первый файл, который xcopy попытается выполнить, то при этом он сразу же сдастся без копирования каких-либо файлов, что удовлетворяет условию копирования файлов.

Хорошая попытка, но нет. Чтобы избежать ожидания коллизии, я непосредственно ставлю точку останова в программе `xcopy` непосредственно перед операцией копирования файла, а когда она достигается, я удаляю файл для копирования. При возобновлении исполняемого файла `xcopy` я получаю код ошибки 4. MC ND 6 лет назад 1