Скопируйте * d.dll в папку отладки и * .dll без * d.dll в релиз - PullRequest
0 голосов
/ 13 января 2019

У меня есть библиотека с файлами типа

opencv_dnn340.dll
opencv_dnn340d.dll
opencv_features2d340.dll
opencv_features2d340d.dll
opencv_ffmpeg340_64.dll
opencv_flann340.dll
opencv_flann340d.dll
opencv_highgui340.dll
opencv_highgui340d.dll
opencv_imgcodecs340.dll
opencv_imgcodecs340d.dll
opencv_imgproc340.dll
opencv_imgproc340d.dll

Я пытаюсь скопировать только файлы * d.dll в режиме отладки. и скопируйте все файлы * .dll без * d.dll в режиме выпуска

Я начал с этого

if %ConfigurationName% == Debug xcopy /y /d "%SolutionDir%..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin\*d.dll" "%TargetDir%\"

else xcopy /y /d "%SolutionDir%..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin\*.dll" "%TargetDir%\"

но в релизе я копирую все файлы.

сейчас я пытаюсь использовать для цикла

for /R "%SolutionDir%..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin\" "%%File" IN *.dll
    if %ConfigurationName% == Debug & findstr /R *d.dll "%%File"
       xcopy /y /d "%%File" "%TargetDir%\"
    else %ConfigurationName% == Release & NEQ findstr /R *d.dll "%%File"
       xcopy /y /d "%%File" "%TargetDir%\"

Не могли бы вы помочь с созданием копии файла * .dll без файлов * d.dll благодаря

Ответы [ 4 ]

0 голосов
/ 13 января 2019

Вот еще одно решение для этой задачи копирования файлов:

@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 /?
0 голосов
/ 13 января 2019

Я создал 3 папки: Libs, Debug и Release. Папка Libs содержит

opencv_dnn340.dll
opencv_dnn340d.dll
opencv_features2d340.dll
opencv_features2d340d.dll

Использование Robocopy Перейти к отладке

robocopy Libs Debug *d.dll

Перейти к выпуску

robocopy Libs Release /XF *d.dll
0 голосов
/ 13 января 2019

Полагаю, вы можете использовать опцию /exclude:exclude_file.txt для этого. Так что если вы поместите свой шаблон туда d.dll и добавите эту опцию в ваш релиз xcopy xcopy /exclude:debug_dlls_pattern.txt, вы получите копию только релиза dll.

0 голосов
/ 13 января 2019

Просто подумайте, чтобы вам не пришлось использовать сложный механизм:

mkdir _tmp_nod_
mkdir _tmp_d_
copy /y /d sourceDir\*.dll _tmp_nod_\
move /y _tmp_nod_\*d.dll _tmp_d_\
IF %ConfigurationName% == Debug (move _tmp_d_\* "%TargetDir%\") ELSE (move _tmp_nod_\* "%TargetDir%\")
:: rd /s /q _tmp_nod_
:: rd /s /q _tmp_d_

То есть скопируйте все эти dll во временную папку и переместите эти *d.dll файлы в другую временную папку, тогда как в предыдущей папке будут только те *.dll s без d, и позже вы сможете выбрать одна временная папка для копирования зависит от условия.

Однако другим способом может быть сначала список *d.dll и сохранение списка в файл txt (возможно, используйте dir /b), а затем, когда xcopy *.dll, используйте этот файл txt в качестве параметра /EXCLUDE:. Это также может привести к исключению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...