Вот еще одно решение для этой задачи копирования файлов:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
if /I "%ConfigurationName%" == "Debug" ( set "FilterOption=" ) else set "FilterOption=/V"
for %%I in ("%SolutionDir%\..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin") do set "DllFolder=%%~fI"
for /F "delims= eol=" %%I in ('dir "%DllFolder%\*.dll" /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /E /I /L %FilterOption% "d.dll"') do %SystemRoot%\System32\xcopy.exe "%DllFolder%\%%I" "%TargetDir%\" /C /D /Q /R /Y >nul
endlocal
Переменная окружения FilterOption
удаляется, соответственно, не определяется, если переменная окружения ConfigurationName
определена, а ее строковое значение не чувствительно к регистру и равно строке Debug
. Во всех остальных случаях переменная среды FilterOption
определяется в локальной настройке среды с помощью setlocal
и endlocal
со строкой значения параметра /V
. Прочитайте этот ответ для получения подробной информации о командах SETLOCAL и ENDLOCAL .
Четвертая строка с первой for
просто определяет полный полный абсолютный путь к папке, содержащей файлы динамически связанных библиотек без относительного пути, который назначен переменной среды DllFolder
.
Пятая строка со вторым for
делает настоящую работу. FOR выполняется в отдельном командном процессе, начинающемся с cmd.exe /C
(точнее с %CompSpec% /C
) в фоновом режиме командной строки:
dir "%DllFolder%\*.dll" /A-D-H /B 2>nul | %SystemRoot%\System32\findstr.exe /E /I /L %FilterOption% "d.dll"
Ссылки на переменные среды уже развернуты в реальном времени при исполнении.
DIR выходы
- только имена всех не скрытых файлов из-за опции
/A-D-H
(атрибут не каталог и не скрытый)
- в голом формате из-за опции
/B
- соответствует шаблону подстановки
*.dll
- в указанном каталоге.
Имена выходных файлов без указания пути к файлу, только имя и расширение файла.
Возможно, что DIR не найдет ничего, соответствующего этим критериям. В этом случае сообщение об ошибке выводится DIR для обработки STDOUT , которое подавляется путем перенаправления его с помощью 2>nul
на устройство NUL .
Выход DIR перенаправляется с |
на STDIN из FINDSTR , который ищет
- в конце каждой строки из-за опции
/E
- без учета регистра из-за опции
/I
- и интерпретировать строку поиска как буквенную строку из-за опции
/L
- для строки
d.dll
и вывод для обработки STDOUT фоновой команды, обрабатывающей все строки, заканчивающиеся d.dll
в FilterOption
, не определены, или обратный результат в FilterOption
, определенный со значением /V
, т.е. все строки не заканчивается d.dll
.
Прочитайте статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul
и |
. Операторы перенаправления >
и |
должны быть экранированы с помощью символа вставки ^
on FOR , чтобы интерпретировать их как буквенные символы, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , который выполняет встроенную командную строку dir
с findstr
в отдельном командном процессе, запущенном в фоновом режиме.
FOR захватывает все выходные данные для обработки STDOUT запущенного фонового командного процесса и обрабатывает этот вывод построчно после того, как запущенный командный процесс завершился сам.
FOR с параметром /F
игнорирует пустые строки, которые здесь не встречаются. FOR также будет игнорировать строки (= имена файлов), начинающиеся с точки с запятой, которые, скорее всего, здесь не встречаются. Но опция конца строки переопределяется с помощью eol=
, чтобы не определять символ как опцию конца строки, которая отключает этот фильтр FOR . FOR также будет разбивать каждую строку на подстроки, используя обычный пробел и горизонтальную табуляцию в качестве разделителей, и назначать только первую строку, разделенную пробелом / табуляцией, для переменной цикла I
. Скорее всего, нет библиотечных файлов с пробелом в имени файла, но с delims=
это разделение строк отключается, если в качестве разделителя не указывать символ.
То есть FOR выполняется для каждого вывода имени файла с помощью DIR , передавая FINDSTR , фильтруя команду XCOPY , чтобы скопировать файл в цель каталог, если исходный файл еще не существует в целевом каталоге с более новой датой последнего изменения, в результате чего XCOPY автоматически создает также всю структуру каталога в целевой каталог, если это необходимо для целевого каталога, который еще не существует.
Можно также использовать COPY вместо XCOPY . Но в этом случае должна быть командная строка md "%TargetDir%" 2>nul
где-то выше второй командной строки FOR , чтобы убедиться, что целевой каталог существует, поскольку COPY не создает автоматически дерево каталогов для целевой каталог.
Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.
dir /?
echo /?
endlocal /?
findstr /?
for /?
if /?
set /?
setlocal /?
xcopy /?