1

I have a library with files like

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

I am trying to copy only the *d.dll files in debug mode and copy all of the *.dll files without *d.dll in release mode

I started with this

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%\"

but in release I copy all of the files.

now I am trying to use for loop

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%\"

Can you please help with how to create a copy for *.dll file without the *d.dll files thanks

Gilad
  • 6,437
  • 14
  • 61
  • 119

4 Answers4

5

I created 3 folders, Libs, Debug and Release. Libs folder contains

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

Using Robocopy Move to Debug

robocopy Libs Debug *d.dll

Move to Release

robocopy Libs Release /XF *d.dll
pagratios
  • 384
  • 2
  • 12
  • if %ConfigurationName% == Debug robocopy %SolutionDir%..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin\" "%TargetDir%\" *d.dll if %ConfigurationName% == Release robocopy %SolutionDir%..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin\" "%TargetDir%\" /XF *d.dll this doesn't work – Gilad Jan 13 '19 at 09:59
  • Could you send the error message? I think something wrong with " happened. The corrected statement might be the -> if %ConfigurationName% == Debug robocopy "%SolutionDir%..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin\" "%TargetDir%\" *d.dll if %ConfigurationName% == Release robocopy "%SolutionDir%..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin\" "%TargetDir%\" /XF *d.dll – pagratios Jan 13 '19 at 10:07
  • >EXEC : error : Invalid Parameter #2 : "G:\Git\IQS\iqs-trunk\ia-tools-iqstudio\iqstudio\Export\Debug" *d.dll" – Gilad Jan 13 '19 at 10:56
  • ok fixed it if %ConfigurationName% == Debug robocopy %SolutionDir%..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin\ %TargetDir%\ *d.dll if %ConfigurationName% == Release robocopy %SolutionDir%..\..\ia-imaging-opencv-libs\3.4.0\windows\x64\vc12\bin\ %TargetDir%\ /XF *d.dll – Gilad Jan 13 '19 at 11:03
0

Just provide a thought, so you need not to use complicated mechanism:

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_

Which is, copy all those dlls to a temporary folder, and move those *d.dll files out to another temporary folder, than the former folder will only have those *.dlls without d, And later you can choose one temporary folder to copy depend on the condition.

However, another way could be list *d.dll first and save the list to a txt file (use dir /b maybe), and later when xcopy *.dll use that txt file as the parameter of /EXCLUDE:. This could also acheive the excluding.

Til
  • 5,150
  • 13
  • 26
  • 34
0

Here is one more solution for this file copying task:

@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

The environment variable FilterOption is deleted respectively not defined if environment variable ConfigurationName is defined and its string value is case-insensitive equal the string Debug. In all other cases the environment variable FilterOption is defined in local environment setup with setlocal and endlocal with the option value string /V. Read this answer for details about the commands SETLOCAL and ENDLOCAL.

The fourth line with first for just determines full qualified absolute path of the folder containing the dynamic linked library files without the relative path parts which is assigned to environment variable DllFolder.

The fifth line with second for makes the real job. FOR executes in a separate command process started with cmd.exe /C (more precise with %CompSpec% /C) in background the command line:

dir "%DllFolder%\*.dll" /A-D-H /B 2>nul | %SystemRoot%\System32\findstr.exe /E /I /L %FilterOption% "d.dll"

The environment variable references are already expanded in real on execution.

DIR outputs

  • just the names of all non-hidden files because of option /A-D-H (attribute not directory and not hidden)
  • in bare format because of option /B
  • matching the wildcard pattern *.dll
  • in the specified directory.

The output file names are without file path, just file name and file extension.

It is possible that DIR finds nothing matching these criteria. In this case an error message is output by DIR to handle STDOUT which is suppressed by redirecting it with 2>nul to device NUL.

The output of DIR is redirected with | to STDIN of FINDSTR which searches

  • at end of every line because of option /E
  • case-insensitive because of option /I
  • and interpreting the search string as literal string because of option /L
  • for the string d.dll

and outputs to handle STDOUT of background command process all lines ending with d.dll on FilterOption not defined or the inverse result on FilterOption defined with value /V, i.e. all lines not ending with d.dll.

Read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul and |. The redirection operators > and | must be escaped with caret character ^ on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with findstr with using a separate command process started in background.

FOR captures everything output to handle STDOUT of started background command process and processes this output line by line after started command process terminated itself.

FOR with option /F ignores empty lines which do not occur here. FOR would also ignore lines (= file names) starting with a semicolon which most likely do not occur here. But the end of line option is redefined with eol= to define no character as end of line option which disables this FOR filter. FOR would also split up every line into substrings using normal space and horizontal tab as delimiters and would assign only first space/tab separated string to loop variable I. There are most likely no library files with a space in file name, but with delims= this line splitting behavior is disabled by defining no character as delimiter.

So FOR executes for every file name output by DIR passing FINDSTR filter the command XCOPY to copy the file to the target directory if the source file does not already exist in target directory with a newer last modification date whereby XCOPY automatically creates also the entire directory structure to target directory if that is necessary on target directory not yet existing.

It would be also possible to use COPY instead of XCOPY. But in this case there should be the command line md "%TargetDir%" 2>nul somewhere above second FOR command line to make sure the target directory exists because of COPY does not create automatically the directory tree to the target directory.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • if /?
  • set /?
  • setlocal /?
  • xcopy /?
Mofi
  • 46,139
  • 17
  • 80
  • 143
-1

I guess you could use option /exclude:exclude_file.txt for that. So if you put your pattern there d.dll and add this option to your release xcopy xcopy /exclude:debug_dlls_pattern.txt you'll get copied only release dll.

Fedor Dikarev
  • 506
  • 3
  • 9