将* d.dll复制到调试文件夹,将没有* d.dll的* .dll复制到发行版

时间:2019-01-13 09:40:37

标签: batch-file

我有一个包含

之类文件的库
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文件 并在发布模式下复制所有不带* d.dll的* .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循环

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 :(得分:2)

我创建了3个文件夹,即Libs,Debug和Release。 Libs文件夹包含

Traceback (most recent call last):

  File "(this is a less than sign)pyshell#3(this is a greater than sign)", line 1, in <module>

print(os.getlogin())
OSError: [Errno 25] Inappropriate ioctl for device

使用Robocopy 转到调试

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

移至发布

robocopy Libs Debug *d.dll

答案 1 :(得分:0)

只需提供一个思路即可,因此您无需使用复杂的机制:

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,而没有d ,然后您可以根据情况选择一个临时文件夹进行复制。

但是,另一种方法可能是先列出*d.dll并将列表保存到txt文件中(也许使用dir /b),然后在xcopy *.dll使用该{{ 1}}文件作为txt的参数。这也可以实现排除。

答案 2 :(得分:0)

这是该文件复制任务的另一种解决方案:

@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是在本地环境设置中使用setlocalendlocal以及选项值字符串/V定义的。阅读this answer,了解有关命令 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 的输出通过|重定向到 FINDSTR STDIN 进行搜索

  • 由于选项/E而在每行末尾
  • 由于选项/I而不区分大小写
  • 并由于选项/L将搜索字符串解释为文字字符串
  • 用于字符串d.dll

并输出以处理后台命令的 STDOUT ,以处理d.dll上以FilterOption结尾的所有行,或以值{定义的FilterOption的反结果{1}},即所有/V结尾的行。

阅读有关Using Command Redirection Operators的Microsoft文章,以获取d.dll2>nul的解释。重定向操作符|>必须用 FOR 命令行上的脱字符号|进行转义,以在Windows命令解释器处理此命令行时将其解释为原义字符。在执行命令 FOR 之前,该命令在后台启动的单独命令过程中以^执行嵌入的dir命令行。

FOR 捕获所有输出以处理启动的后台命令进程的 STDOUT ,并在启动命令进程自身终止后逐行处理此输出。

带有选项findstr

FOR 会忽略此处未出现的空行。 FOR 还将忽略以分号开头的行(=文件名),这极有可能不在此处出现。但是使用/F重新定义了行尾选项,以将没有字符定义为行尾选项,这会禁用此 FOR 过滤器。 FOR 还将使用常规空格和水平制表符作为分隔符将每一行拆分为子字符串,并且仅将第一个空格/制表符分隔的字符串分配给循环变量eol=。很有可能没有文件名中带有空格的库文件,但是使用I时,通过不将任何字符定义为定界符来禁用此行拆分行为。

因此 FOR DIR 输出的每个文件名执行,并传递 FINDSTR 过滤命令 XCOPY 以复制如果源文件在目标目录中尚不存在且上次修改日期较新,则文件会被保存到目标目录中,从而 XCOPY 还会自动创建目标目录的整个目录结构(如果尚未在目标目录上创建)现有。

也可以使用 COPY 代替 XCOPY 。但是在这种情况下,应该在第二个 FOR 命令行上方的某个位置放置命令行delims=,以确保目标目录存在,因为 COPY 不会自动创建目录树到目标目录。

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • md "%TargetDir%" 2>nul
  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • if /?
  • set /?
  • setlocal /?

答案 3 :(得分:-1)

我想您可以为此使用选项/exclude:exclude_file.txt。 因此,如果您将模式放在d.dll处,并将此选项添加到发行版xcopy xcopy /exclude:debug_dlls_pattern.txt中,则只会复制发行版dll。