VS预生成事件/生成后事件

命令行

打开项目,右击项目,打开属性—>配置属性–>生成事件,如图所示:
这里写图片描述

 可以在命令行中直接填入copy,xcopy等DOS文件复制命令。如同下图所示:
这里写图片描述
可以在拷贝命令行中看到诸如TargetPath, ProjectDir, ProjectName, TargetDir。而具体这些变量的值可以在点击宏之后弹出的框中查找具体含义:
这里写图片描述

VS官方帮助网站提供了详尽的的宏命令使用说明与参考,此处转载如下:

宏                                           说明
$(ConfigurationName)    当前项目配置的名称,例如,“调试”。
$(OutDir)    相对于项目目录的输出文件目录的路径。 这解析为输出目录属性的值。 它包括尾随反斜杠“\”。
$(DevEnvDir)    Visual Studio 的安装目录(使用驱动器和路径进行定义);包括尾随反斜杠“\”。
$(PlatformName)    当前目标平台的名称。 例如,“AnyCPU”。
$(ProjectDir)    项目的目录(使用驱动器和路径进行定义);包括尾随反斜杠“\”。
$(ProjectPath)    项目的绝对路径名称(使用驱动器、路径、基名称和文件扩展名进行定义)。
$(ProjectName)    项目的基名称。
$(ProjectFileName)    项目的文件名称(使用基名称和文件扩展名进行定义)。
$(ProjectExt)    项目的文件扩展名。 文件扩展名之前包括“.”。
$(SolutionDir)    解决方案的目录(使用驱动器和路径进行定义);包括尾随反斜杠“\”。
$(SolutionPath)    解决方案的绝对路径(使用驱动器、路径、基名称和文件扩展名进行定义)。
$(SolutionName)    解决方案的基名称。
$(SolutionFileName)    解决方案的文件名称(使用基名称和文件扩展名进行定义)。
$(SolutionExt)    解决方案的文件扩展名。 文件扩展名之前包括“.”。
$(TargetDir)    生成的主输出文件的目录(使用驱动器和路径进行定义)。 它包括尾随反斜杠“\”。
$(TargetPath)    生成的主输出文件的绝对路径名称(使用驱动器、路径、基名称和文件扩展名进行定义)。
$(TargetName)    生成的主输出文件的基名称。
$(TargetFileName)    生成的主输出文件的文件名称(使用基名称和文件扩展名进行定义)。
$(TargetExt)    生成的主输出文件的文件扩展名。 文件扩展名之前包括“.”。

 语法

if not exist "$(TargetDir)AudioSource" md "$(TargetDir)AudioSource" // 如果不存在AudioSource目录 就创建改目录

copy "$(SolutionDir)Source\Model\AlarmHandle\Audio\ALARM1.WAV" "$(projectDir)$(OutDir)\AudioSource\ALARM1.WAV //然后将WAV文件copy到 这个目录下(要包含文件名)。
....
call  "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" // 还可以调用bat文件。 
xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"// xcopy 将目录下非空的目录和子目录都copy到另外一个目录下。

if/else

if $(ConfigurationName) == Debug (
  copy "$(TargetDir)myapp.dll" "c:\delivery\bin" /y
  copy "$(TargetDir)myapp.dll.config" "c:\delivery\bin" /y
) ELSE (
  echo "why, Microsoft, why".
)

if not exist "$(TargetDir)AudioSource" md "$(TargetDir)AudioSource" // 如果不存在AudioSource目录 就创建改目录

如果需要的生成事件涉及比较复杂的删除目录,删除文件,拷贝目录,拷贝子目录,等操作,可能需要撰写比较多的命令,为了简化,可以把这些拷贝,删除动作组织成一个bat文件,如下图所示:

这里写图片描述

而该文件的内容由之前的copy类似的命令组成,内容如下:

::清除旧文件
del /S /Q "%~dp0"Bin\*.dll
del /S /Q "%~dp0"Bin\*.dll
rd /S /Q "%~dp0"Bin\hplugin
rd /S /Q "%~dp0"Bin\hplugin

::公共DLL
xcopy /Y "%~dp0"..\dll\HLOG.* "%~dp0"Release\
xcopy /Y "%~dp0"..\dll\hpr.* "%~dp0"Release\
xcopy /Y "%~dp0"..\dll\Identify.* "%~dp0"Release\
xcopy /Y "%~dp0"..\dll\libeay32.* "%~dp0"Release\
xcopy /Y "%~dp0"..\dll\RegexInterface.* "%~dp0"Release\
xcopy /Y "%~dp0"..\dll\EncryptInterface.* "%~dp0"Release\
xcopy /Y "%~dp0"..\dll\hplug.* "%~dp0"Release\
xcopy /Y "%~dp0"..\dll\RemoteDeviceSocket.* "%~dp0"Release\
xcopy /Y "%~dp0"..\dll\CrashAPI.* "%~dp0"Release\

xcopy /Y "%~dp0"..\dll\HLOG.dll "%~dp0"Bin\
xcopy /Y "%~dp0"..\dll\hpr.dll "%~dp0"Bin\
xcopy /Y "%~dp0"..\dll\Identify.dll "%~dp0"Bin\
xcopy /Y "%~dp0"..\dll\libeay32.dll "%~dp0"Bin\
xcopy /Y "%~dp0"..\dll\RegexInterface.dll "%~dp0"Bin\
xcopy /Y "%~dp0"..\dll\EncryptInterface.dll "%~dp0"Bin\
xcopy /Y "%~dp0"..\dll\hplug.dll "%~dp0"Bin\
xcopy /Y "%~dp0"..\dll\RemoteDeviceSocket.dll "%~dp0"Bin\
xcopy /Y "%~dp0"..\dll\CrashAPI.dll "%~dp0"Bin\

%~dp0 是盘符加路径,即该CopyBuildFile.bat文件所在的目录

D:\Git\004_c_components\DeviceAccess

bat命令 

在生成事件中,常涉及的命令有文件的拷贝或者删除,目录的创建和删除,因此在这种情景下,需要弄清楚如下的命令。

del

C:\Windows\SysWOW64>del /?
删除一个或数个文件。

DEL [/P] [/F] [/S] [/Q] [/A[[:]attributes]] names
ERASE [/P] [/F] [/S] [/Q] [/A[[:]attributes]] names

  names         指定一个或多个文件或者目录列表。
                通配符可用来删除多个文件。
                如果指定了一个目录,该目录中的所
                有文件都会被删除。

  /P            删除每一个文件之前提示确认。
  /F            强制删除只读文件。
  /S            删除所有子目录中的指定的文件。
  /Q            安静模式。删除全局通配符时,不要求确认
  /A            根据属性选择要删除的文件
  属性          R  只读文件                     S  系统文件
                H  隐藏文件                     A  存档文件
                I  无内容索引文件               L  重分析点
                -  表示“否”的前缀

如果命令扩展被启用,DEL 和 ERASE 更改如下:

/S 开关的显示句法会颠倒,即只显示已经
删除的文件,而不显示找不到的文件。

copy

C:\Windows\SysWOW64>copy /?
将一份或多份文件复制到另一个位置。

COPY [/D] [/V] [/N] [/Y | /-Y] [/Z] [/L] [/A | /B ] source [/A | /B]
     [+ source [/A | /B] [+ ...]] [destination [/A | /B]]

  source       指定要复制的文件。
  /A           表示一个 ASCII 文本文件。
  /B           表示一个二进位文件。
  /D           允许解密要创建的目标文件
  destination  为新文件指定目录和/或文件名。
  /V           验证新文件写入是否正确。
  /N           复制带有非 8dot3 名称的文件时,
               尽可能使用短文件名。
  /Y           不使用确认是否要覆盖现有目标文件
               的提示。
  /-Y          使用确认是否要覆盖现有目标文件
               的提示。
  /Z           用可重新启动模式复制已联网的文件。
/L           如果源是符号链接,请将链接复制
               到目标而不是源链接指向的实际文件。

命令行开关 /Y 可以在 COPYCMD 环境变量中预先设定。
这可能会被命令行上的 /-Y 替代。除非 COPY
命令是在一个批处理脚本中执行的,默认值应为
在覆盖时进行提示。

要附加文件,请为目标指定一个文件,为源指定
数个文件(用通配符或 file1+file2+file3 格式)。

C:\Windows\SysWOW64>

xcopy

C:\Windows\SysWOW64>xcopy /?
复制文件和目录树。

XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W]
                           [/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/U]
                           [/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z] [/B]
                           [/EXCLUDE:file1[+file2][+file3]...]

  source       指定要复制的文件。
  destination  指定新文件的位置和/或名称。
  /A           仅复制有存档属性集的文件,但不更改属性。
  /M           仅复制有存档属性集的文件,并关闭存档属性。
  /D:m-d-y     复制在指定日期或指定日期以后更改的文件。
               如果没有提供日期,只复制那些源时间比目标时间新的文件。
  /EXCLUDE:file1[+file2][+file3]...
               指定含有字符串的文件列表。每个字符串在文件中应位于单独的一行。
               如果任何字符串与复制文件的绝对路径的任何部分相符,则排除复制
               该文件。例如,指定如 \obj\ 或 .obj 的字符串会分别排除目录
               obj 下面的所有文件或带有 .obj 扩展名的所有文件。
  /P           创建每个目标文件之前提示您。
  /S           复制目录和子目录,不包括空目录。
  /E           复制目录和子目录,包括空目录。与 /S /E 相同。可以用来修改 /T。
  /V           验证每个新文件的大小。
  /W           提示您在复制前按键。
  /C           即使有错误,也继续复制。
  /I           如果目标不存在,且要复制多个文件,则假定目标必须是目录。
  /Q           复制时不显示文件名。
  /F           复制时显示完整的源文件名和目标文件名。
  /L           显示要复制的文件。
  /G           允许将加密文件复制到不支持加密的目标。
  /H           也复制隐藏文件和系统文件。
  /R           覆盖只读文件。
  /T           创建目录结构,但不复制文件。不包括空目录或子目录。/T /E 包括
               空目录和子目录。
  /U           只复制已经存在于目标中的文件。
  /K           复制属性。一般的 Xcopy 会重设只读属性。
  /N           用生成的短名称复制。
  /O           复制文件所有权和 ACL 信息。
  /X           复制文件审核设置(隐含 /O)。
  /Y           取消提示以确认要覆盖现有目标文件。
  /-Y          要提示以确认要覆盖现有目标文件。
  /Z           在可重新启动模式下复制网络文件。
  /B           复制符号链接本身与链接目标相对。
  /J           复制时不使用缓冲的 I/O。推荐复制大文件时使用。

开关 /Y 可以预先在 COPYCMD 环境变量中设置。
这可能被命令行上的 /-Y 覆盖。

/EXCLUDE

xcopy /Y /S "%~dp0"..\Devices\* "%~dp0"Release\hplugin\ /EXCLUDE:%~dp0\HpluginExclude.txt

通配符

xcopy /Y /S "%~dp0"Release\*.pdb "%~dp0"PDB\

 rd

D:\Git\004_c_components\Devices>rd /?
删除一个目录。

RMDIR [/S] [/Q] [drive:]path
RD [/S] [/Q] [drive:]path

    /S      除目录本身外,还将删除指定目录下的所有子目录和
            文件。用于删除目录树。

    /Q      安静模式,带 /S 删除目录树时不要求确认

md

D:\Git\004_c_components\Devices>md /?
创建目录。

MKDIR [drive:]path
MD [drive:]path

如果命令扩展被启用,MKDIR 会如下改变:

如果需要,MKDIR 会在路径中创建中级目录。例如: 假设 \a 不
存在,那么:

    mkdir \a\b\c\d

与:

    mkdir \a
    chdir \a
    mkdir b
    chdir b
    mkdir c
    chdir c
    mkdir d