惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
罗磊的独立博客
IT之家
IT之家
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
博客园 - Franky
博客园 - 聂微东
博客园_首页
爱范儿
爱范儿
量子位
博客园 - 三生石上(FineUI控件)
G
Google Developers Blog
Martin Fowler
Martin Fowler
小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Y
Y Combinator Blog
Vercel News
Vercel News
腾讯CDC
Microsoft Azure Blog
Microsoft Azure Blog
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Cloudflare Blog
Engineering at Meta
Engineering at Meta

博客园 - zhaotianff

WPF控件样式和模板全解析-ToolTip控件 WPF控件样式和模板全解析-RadioButton控件 WPF控件样式和模板全解析-ToggleButton控件 WPF控件样式和模板全解析-CheckBox控件 软件架构风格与软件架构设计方法 WPF控件样式和模板全解析-Label控件 WPF控件样式和模板全解析-Button控件 Windows一直卡在检查更新的解决方案 - zhaotianff - 博客园 AI时代,程序员应该何去何从? C++中的explicit关键字 如何解决Windows 10/11 删除打印机时,拒绝访问的问题 解决IIS服务器typecho上传附件后无法访问的问题 Jenkins快速入门教程 .NET是什么?为什么要选择.NET? 如何在WPF中实现类似DevOps的自动化流程 一文带你搞懂医疗器械设计开发全生命周期 Windows如何清除本机记录的git用户名和密码 HL7协议详解 医疗行业 GDT 数据格式详解 一文带你搞懂C# 异步编程(async/await)底层原理 如何在C#中使用Chromium headless(无头模式)浏览器 不同.NET版本中的WPF新增功能 如何在WPF中使用 Fluent 主题 Windows平台下的各种原生UI框架介绍 C#如何Hook托管函数 WinDbg 用户层调试进阶教程 Windows编程的一些基础理论 推荐一款优秀的Windows经典文件管理器项目-WinFile Windows如何阻止应用程序联网 如何在WPF中捕获窗口外的事件
Visual Studio编译过程中拷贝文件的一些实用小技巧
zhaotianff · 2026-07-03 · via 博客园 - zhaotianff

有时候我们在编译项目前可能会需要拷贝一些文件,或者在编译完成后,将生成的文件拷贝到固定的位置。

场景1

我有一个三方的sdk,这个sdk已经放在项目里了。

有时候我们需要集成一个C++的动态链接库,它内部是动态调用的(通过LoadLibrary)。

在C#层是通过P/Invoke进行调用,一般会提供一个接口层,运行时,还需要另外一个dll.

如果我们每次把文件都手动复制到输出目录,就略显麻烦。特别是换了电脑,换了输出路径的情况下。

这种场景实现比较简单,只要设置一下属性,将文件始终复制到输出目录即可。

image

image

这样我们编译后,就可以看到文件已经自动复制到输出路径了。

image

场景2

我需要将生成的文件拷贝到其它路径。

这种比较常见的就是使用了Prism,将模块进行了统一管理,并通过目录加载的形式进行加载。

例如这里我配置了通过Device目录加载模块

1 protected override IModuleCatalog CreateModuleCatalog()
2 {
3     return new DirectoryModuleCatalog() { ModulePath = @".\Device" };
4 }

我们现在有一个Device.Keyboard工程,需要在编译完成后,把这个dll复制到项目输出路径下的Device目录下。

这个时候我们可以编辑生成后事件,使用xcopy命令来进行拷贝(关于xcopy命令的详细使用参考:https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/xcopy

image

Visual Studio中.NET Core/.NET工程的配置界面

image

 Visual Studio 中.NET Framework工程的配置界面

输入以下指令

1 xcopy /Y /R "$(TargetPath)" "$(OutDir)Device\"

就可以在编译成功时自动将当前的项目的输出文件拷贝到输出路径下的Device文件夹

image

 这里我们使用了一些预生成宏,常见的宏定义如下:

说明
$(Configuration) 当前项目配置的名称,例如,“调试”。
$(DevEnvDir) Visual Studio 的安装目录(定义为驱动器 + 路径);包括尾随反斜杠 (\)。
$(FrameworkDir) 在其中安装了 .NET Framework 的目录。
$(FrameworkSDKDir) 在其中安装了 .NET Framework 的目录。 .NET Framework 可能已作为 Visual Studio 的一部分安装或已单独安装。
$(FrameworkVersion) Visual Studio 使用的.NET framework 版本。 结合 $(FrameworkDir),就是 Visual Studio 使用的 .NET Framework 版本的完整路径。
$(FxCopDir) fxcop.cmd 文件的路径。 fxcop.cmd 文件并未在所有 Visual Studio 版本中安装。
$(IntDir) 为中间文件指定的目录路径。 如果这是一个相对路径,中间文件将转到已追加到项目目录的这一路径。 此路径应包含尾随斜杠 (\)。 它解析为“中间目录”属性的值。 请勿使用 $(OutDir) 来定义此属性。
$(OutDir) 输出文件目录的路径。 如果这是一个相对路径,输出文件将转到已追加到项目目录中的这一路径。 此路径应包含尾随斜杠 (\)。 它解析为“输出目录”属性的值。 请勿使用 $(IntDir) 来定义此属性。
$(Platform) 当前项目平台的名称(例如“Win32”)。
$(PlatformShortName) 当前体系结构的短名称,例如“x86”或“x64”。
$(ProjectDir) 项目的目录(定义为驱动器 + 路径);包括尾随反斜杠 (\)。
$(ProjectExt) 项目的文件扩展名。 文件扩展名之前包括“.”。
$(ProjectFileName) 项目的文件名称(定义为基名称 + 文件扩展名)。
$(ProjectName) 项目的基名称。
$(ProjectPath) 项目的绝对路径名称(定义为驱动器 + 路径 + 基名称 + 文件扩展名)。
$(PublishDir) 发布目标的输出位置;包括尾随反斜杠 (\)。 默认为 $(OutDir)app.publish\ 文件夹。
$(RemoteMachine) 设置为“调试”属性页上 Remote Machine 属性的值。 有关详细信息,请参阅更改 C/C++ 调试配置的项目设置
$(RootNameSpace) 包含应用程序的命名空间(如果存在)。
$(SolutionDir) 解决方案的目录(定义为驱动器 + 路径);包括尾随反斜杠 (\)。 仅当在 IDE 中生成解决方案时定义。
$(SolutionExt) 解决方案的文件扩展名。 文件扩展名之前包括“.”。 仅当在 IDE 中生成解决方案时定义。
$(SolutionFileName) 解决方案的文件名称(定义为基名称 + 文件扩展名)。 仅当在 IDE 中生成解决方案时定义。
$(SolutionName) 解决方案的基名称。 仅当在 IDE 中生成解决方案时定义。
$(SolutionPath) 解决方案的绝对路径名称(定义为驱动器 + 路径 + 基名称 + 文件扩展名)。 仅当在 IDE 中生成解决方案时定义。
$(TargetDir) 生成的主输出文件的目录(定义为驱动器 + 路径);包括尾随反斜杠 (\)。
$(TargetExt) 生成的主输出文件的文件扩展名。 文件扩展名之前包括“.”。
$(TargetFileName) 生成的主输出文件的文件名称(定义为基名称 + 文件扩展名)。
$(TargetName) 生成的主输出文件的基名称。
$(TargetPath) 生成的主输出文件的绝对路径名称(定义为驱动器 + 路径 + 基名称 + 文件扩展名)。
$(VCInstallDir) 包含 Visual Studio 安装的 C++ 内容的目录。 此属性包含目标 Microsoft C++ (MSVC) 工具集的版本,它可能与主机 Visual Studio 不同。 例如,当使用 $(PlatformToolset) = v140 进行生成时,$(VCInstallDir) 包含 Visual Studio 2015 安装路径。
$(VSInstallDir) 在其中安装了 Visual Studio 的目录。 此属性包含目标 Visual Studio 工具集的版本,它可能与主机 Visual Studio 不同。 例如,当使用 $(PlatformToolset) = v110 进行生成时,$(VSInstallDir) 包含 Visual Studio 2012 安装路径。
$(WebDeployPath) 从 Web 部署根到项目输出位置的相对路径。
$(WebDeployRoot) <localhost> 位置的绝对路径。 例如 c:\inetpub\wwwroot

 详见:https://www.cnblogs.com/zhaotianff/p/19117283

场景3

我需要将生成的文件压缩 

这里我们还是使用生成后事件,并使用tar命令进行压缩 

以下指令的功能是将输出目录下的全部文件压缩到D:\Compressed.zip文件

1 tar -caf D:\Compressed.zip -C $(OutDir) *

场景4

我需要在生成完成后生成安装包

这里我们可以借助Inno Setup或NSIS等支持命令行 / 脚本批量打包的安装包制作工具。

在生成后事件里,使用对应的命令执行打包,例如

2 ISCC /d"Version=1.1.0" build_script.iss

关于Inno SetupNSIS等工具的使用可以参考以下文档,这里不做详细介绍。

Inno Setup

https://jrsoftware.org/ishelp/

NSIS

https://nsis.sourceforge.io/Docs/