尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Visual Studio新建文件自动添加注释:项模板与模板宏改造指南

Visual Studio新建文件自动添加注释:项模板与模板宏改造指南 1. 为什么值得花时间改造 Visual Studio 新建文件模板Visual Studio 里新建文件之后自动添加注释这件事我前前后后折腾过四五轮从小作坊式的复制粘贴到最后把项模板文件直接改掉中间踩的坑不算少。如果你每天要在 Visual Studio 里新建七八个甚至几十个源文件每次光标落在空白页面上都要手动敲一遍版权声明、作者、创建日期、模块说明那你一定懂那种机械劳动消耗注意力的烦躁。更麻烦的是十个人写十种格式代码评审的时候光对齐文件头就能吵上十分钟。这篇内容想解决的就是这个具体问题让 Visual Studio 在你点击添加新项、选择类文件或 C 源文件的那一刻自动把预先设计好的注释头填进去作者、时间、命名空间、文件名这些还会自动替换成真实值。它适合所有用 Visual Studio 写 C#、C、Python 或者其他语言的开发者不管你是刚装好 Visual Studio 2022 Community 的新手还是用了很多年 visual studio 2019 一直没动过模板的老手都能照着做。核心手段是把 Visual Studio 自带的项模板文件Item Template改成你想要的样子再清掉缓存让它生效整个过程不需要装任何插件。我不会只丢给你一段模板代码就完事。改模板这件事看着简单真正的坑全在细节里改哪个目录才生效、中文乱码从哪来、$ 参数宏到底有哪些能用哪些不能、改完之后为什么添加新项里还是老样子、团队里怎么统一分发。这些我会一个个拆开讲包括我实测有效的路径和命令。2. 自动注释的三种实现路线与选型对比在动手之前先想清楚走哪条路。Visual Studio 生态里能实现新建文件自动加注释的方案至少有四种它们的生效范围、维护成本和长期稳定性差别很大选错了后面会反复返工。2.1 四条可行路线各自的特点第一条路是直接修改 Visual Studio 安装目录下的项模板文件。这是最彻底的做法改完之后整个 IDE 里所有通过添加新项创建的文件都会带上注释头不需要任何额外操作也不依赖插件。代价是安装目录通常需要管理员权限而且大版本升级或修复安装时有可能被覆盖。第二条路是导出自定义项模板。你先手写一个带注释头的模板文件通过项目 → 导出模板或者手动打包成 zip 丢进用户模板目录之后在添加新项对话框里就能选到它。好处是完全不碰安装目录可以放进 Git 仓库让全组同步坏处是每个开发者得自己导入一次新人容易漏。第三条路是代码片段Code Snippet。把注释头做成 snippet用快捷键触发插入。它的问题是半自动——你得记得按快捷键忘了就没了本质上没解决自动这两个字。我早年用过一段时间最后放弃了因为总有漏掉的时候。第四条路是第三方扩展。市面上确实有专门做文件头管理的扩展功能也齐全能自动更新时间、支持多语言模板。但要考虑扩展的维护状态、团队统一安装的成本以及在企业环境里的合规审查。如果只是自己用扩展是最省事的如果要全组推广我还是倾向改模板。方案生效范围触发方式维护成本升级影响推荐场景修改项模板文件全 IDE 全局完全自动中需处理缓存可能被修复安装覆盖个人长期使用、固定团队导出自定义项模板导入者可见完全自动低但需分发基本无影响小团队、跨机器同步代码片段 Snippet个人手动快捷键低无临时救急、非高频场景第三方扩展个人或团队完全自动低依赖扩展跟随扩展更新不想折腾文件路径的人2.2 我更倾向改模板文件的原因理由很直白一次配置长期受益而且是零心智负担的。注释头这种东西本来就该是无感的如果还需要人主动触发那迟早会漏。我手上有几个项目从 visual studio 2019 一直带到 visual studio 2022模板改法跨版本几乎没有变化说明这套机制足够稳定。至于被覆盖的风险实际上只要你不做修复安装正常的功能更新很少动 ItemTemplates 目录而且我习惯把改好的模板文件在 Git 仓库里留一份真被覆盖了一分钟就能还原。需要提前说清楚的是我下面的做法是基于 Visual Studio 2022 的英文/中文混合环境实测的不同版本号Community、Professional、Enterprise只是安装根目录里的版本标识不同后面的相对路径完全一致。如果你用的是 visual studio code 而不是完整的 Visual Studio那机制完全不同我在后面单独开一节讲。3. 搞懂项模板机制文件放哪、宏怎么用磨刀不误砍柴工。改模板之前必须搞清楚两件事模板文件到底躺在什么位置以及模板里那些用$包起来的占位符是什么意思。搞明白这两点你就不是在照抄一段代码而是能自己定制出任何你想要的文件头。3.1 项目模板和项模板不是一回事Visual Studio 里有两类模板名字很像但用途完全不同。项目模板Project Template决定的是你新建一个项目时生成什么比如新建一个控制台应用会生成 csproj、Program.cs、Properties 目录这一整套。项模板Item Template决定的是你在已有项目里点添加 → 新建项时生成什么比如选类就生成一个 Class.cs选接口就生成一个 Interface.cs。我们要改的是项模板因为新建文件自动加注释说的就是单个文件的场景。这一点很多人一开始会搞混跑去改项目模板结果新建单个类文件还是没注释白白浪费时间。项模板的核心目录在这里以 VS 2022 Community 为例Professional 和 Enterprise 只需把 Community 换成对应名字C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\ItemTemplates\这个目录下面按语言和场景分了子目录结构大致是这样路径片段含义ItemTemplates\CSharp\Code\2052\Class\C# 的类项模板2052 表示中文ItemTemplates\CSharp\Code\1033\Class\C# 的类项模板1033 表示英文ItemTemplates\CSharp\Code\2052\Interface\C# 的接口项模板ItemTemplates\Web\Web 相关项模板VC\VCProjectItems\newcfile.cppC 新建 .cpp 文件时使用的模板注意这个在 VC 目录下注意2052是简体中文的语言代码1033是美式英语。如果你装的是中文版 Visual Studio实际生效的是 2052 目录下的文件改 1033 那套是没用的。不确定的话两个目录都看一下哪个里面的文件内容和添加新项出来的文件一致就改哪个。3.2 模板参数宏让注释头自己会填内容模板文件里那些$username$、$rootnamespace$不是随便写的它们叫模板参数Template ParametersVisual Studio 在生成文件的那一刻会把它们替换成真实值。这是整套方案里最有价值的部分因为时间、作者、命名空间这些信息全靠它自动填。常用的宏我整理成表都是我在实际模板里验证过能用的宏替换结果典型用途$itemname$当前项的名称含扩展名注释头里的文件名$safeitemname$去掉非法字符后的项名类名、标识符$safeitemrootname$不含扩展名的安全项名类名、结构体名$rootnamespace$项目的根命名空间C# 文件的命名空间$projectname$项目名称版权归属、模块标识$username$当前登录用户名作者字段$machinename$计算机名调试环境标识$userdomain$当前用户所在域企业环境标识$year$当前年份四位创建日期$month$当前月份创建日期$day$当前日期创建日期$time$当前时间字符串创建时间戳$guid1$到$guid10$生成一个 GUID唯一标识、文件编号$registeredorganization$注册组织名版权声明$targetframeworkversion$目标框架版本条件编译判断这里有个很关键的细节$time$的格式是跟随系统区域设置走的中文环境下通常输出成2024/5/20 14:32:10这种形式。如果你希望时间戳是标准的2024-05-20 14:32:10靠模板宏做不到得改用后面的扩展方案或者干脆接受系统格式。我自己的做法是接受默认格式因为团队里所有人都一样反而统一。还有一个容易忽略的点$username$取的是 Windows 登录名如果你的机器登录名是admin或者user那注释头里全是admin看起来就很敷衍。企业环境里通常有域账号这时候可以用$username$配合$userdomain$组合成类似DOMAIN\zhangsan的形式可读性会好很多。4. 手把手改造从备份到生效的完整流程前面都是铺垫这一节开始动手。我按照准备 → 改造 C# 模板 → 改造 C 模板 → 让改动生效的顺序来每一步都给出具体路径和文件内容你可以直接对照操作。4.1 动手前必须做的两件准备第一件事是备份。安装目录下的原始模板文件一定要先复制一份到别的地方比如桌面建个vs-template-backup文件夹。原因很简单模板改坏了添加新项会直接报错或者生成空文件那个体验非常糟糕而且新手很难第一时间意识到是模板的问题。有备份在手还原只需要覆盖回去。第二件事是关闭 Visual Studio。Visual Studio 在运行时会占用模板文件句柄你在 IDE 开着的情况下改文件改完之后它可能直接从内存缓存里读旧内容导致你以为改了没生效。老老实实关掉 IDE改完再开能省掉一大半排查时间。第三件事严格来说算第三件用管理员身份打开编辑器。C:\Program Files\下面的目录默认需要提权才能写。我一般用管理员身份启动 Notepad 或者 VS Code直接打开目标文件编辑保存。如果用普通记事本打开会提示保存失败需要权限很多人在这一步卡住以为是文件被占用。4.2 改造 C# 类模板让每个新类都有注释头目标文件位置C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\ItemTemplates\CSharp\Code\2052\Class\Class.cs用管理员权限打开它原始内容大概是这样的不同版本略有差异核心结构一致using System; using System.Collections.Generic; $if$ ($targetframeworkversion$ 3.5)using System.Linq; $endif$using System.Text; namespace $rootnamespace$ { class $safeitemrootname$ { } }我要在每个新类的最上方加一段注释块改完之后长这样// // 文件名称 : $itemname$ // 所属命名空间 : $rootnamespace$ // 创建者 : $username$ // 创建日期 : $year$/$month$/$day$ // 创建时间 : $time$ // 功能描述 : 待补充 // using System; using System.Collections.Generic; $if$ ($targetframeworkversion$ 3.5)using System.Linq; $endif$using System.Text; namespace $rootnamespace$ { class $safeitemrootname$ { } }这里有几个设计上的考量值得说一下。第一条分隔线用等号而不是减号是因为 Visual Studio 的代码折叠功能会把连续的注释行当成一个块用等号视觉上更醒目一眼就能看出文件头在哪里结束。功能描述留成待补充而不是空着是因为空着的时候很容易被忽略而待补充这三个字在代码评审或者搜索 TODO 的时候会被自然捞出来形成一种软性提醒。作者字段用$username$配合前面说的域账号问题如果你们公司用户名不可读可以直接把这行改成写死的内容比如固定写上团队名反而更清晰。改完保存的时候要留意编码。如果原文件是 UTF-8 带 BOM你保存成 UTF-8 无 BOM中文注释有可能在某些环境下显示成乱码。稳妥的做法是保持原文件编码不变Notepad 底部状态栏能看到当前编码保存时选转为 UTF-8-BOM或者直接用以原编码保存。4.3 改造 C 模板重点在 newcfile.cppC 的情况和 C# 不太一样它不在 ItemTemplates 目录里而是有一个专门的、被无数人改过的文件C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\VC\VCProjectItems\newcfile.cpp这个文件默认内容基本是空的或者只有一行#include iostream之类的。你往里写什么新建的 .cpp 文件里就有什么。我通常这么写/* * 文件名称 : $itemname$ * 所属项目 : $projectname$ * 创建者 : $username$ * 创建日期 : $year$/$month$/$day$ * 功能说明 : 待补充 * 修改记录 : * 1. $year$/$month$/$day$ $username$ 首次创建 * */ #include iostream #include string #include vector #include algorithm using namespace std;注意我额外加了修改记录这一小节。C 项目往往生命周期长一个文件被多个人改来改去文件头里留一个标准的修改记录位比在函数里随手写注释要规范得多也方便做版本追溯。至于#include部分这个视项目而定——如果你的项目用预编译头比如stdafx.h或者pch.h那这里应该改成#include pch.h否则编译会报重复定义或者预编译头不匹配的错。这一点我是踩过坑的模板里写了#include algorithm结果和预编译头冲突报了一堆重定义错误还以为是编译器坏了。4.4 清缓存与重新注册让改动真正生效改完文件不代表立刻生效因为 Visual Studio 会把模板缓存到用户目录下%LOCALAPPDATA%\Microsoft\VisualStudio\17.0_xxxxxxxx\ItemTemplatesCache17.0是 VS 2022 的主版本号VS 2019 对应16.0后面的随机后缀每台机器不同。我一般按这个顺序处理从轻到重直接删掉 ItemTemplatesCache 文件夹。关掉 Visual Studio删掉整个文件夹重新打开 IDE它会自动重建缓存。这是最省事的一招我实测有效。如果删缓存还不行用管理员权限打开命令行执行cd C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE devenv.exe /installvstemplates还不行的话用/setup参数重新注册整个 IDEcd C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE devenv.exe /setup注意devenv.exe /setup会比较慢中途界面可能假死这是正常的不要强行结束进程。另外这两个命令都要在 Visual Studio 完全关闭的状态下执行否则会提示实例正在运行。实测下来绝大多数情况用第 1 招就够了。第 2、3 招更像是兜底主要应对那种改了模板、删了缓存但新文件还是旧内容的情况——通常是因为改动的是 1033 目录或者改的文件根本不是实际生效的那个。5. 非 C# 场景与 Visual Studio Code 的应对方案不是每个人都只写 C#。Python、JavaScript、Markdown 甚至是纯文本文件也可能需要统一的文件头注释。这一节说说其他语言在 Visual Studio 里怎么做以及如果你用的是 visual studio code该怎么处理。5.1 其他语言在 Visual Studio 里的做法Visual Studio 对不同语言的支持是由工作负载决定的。装了 Python 工作负载ItemTemplates下面就会出现 Python 相关的子目录装了 Node.js 工具也会有对应的模板目录。思路完全一样先通过实际新建一个文件观察生成内容再顺着内容去反查是哪个模板文件生成的。具体怎么反查我的做法是用 Everything 这类文件搜索工具或者 Windows 自带的搜索在Common7\IDE目录里搜模板文件里出现的特征字符串。比如新建一个 Python 文件内容里有一行# -*- coding: utf-8 -*-那就搜这个字符串命中的.py文件八成就是模板文件。这招比逐个目录翻要快得多尤其是装了多个工作负载之后ItemTemplates 里的目录层级可能有三四层深。Markdown 文件要注意一点Visual Studio 原生对.md的支持比较有限很多时候是作为普通文本文件处理的。如果你想给.md也加统一的头部注释直接用 HTML 注释!-- --包起来就行这样渲染出来不会显示。至于热词里提到的怎么新建 .md 后缀文件在 Visual Studio 里一般是添加新项 → 文本文件然后手动把扩展名改成.md因为 IDE 有时不会在模板列表里直接给 Markdown 选项。5.2 Visual Studio Code 用户怎么做visual studio code 没有项模板这套机制但有等价甚至更灵活的方案用户代码片段User Snippet。打开文件 → 首选项 → 配置用户代码片段选择对应语言或者新建一个全局片段文件然后写 JSON{ File Header Comment: { prefix: header, body: [ // , // 文件名称 : ${TM_FILENAME}, // 创建者 : 你的名字, // 创建日期 : ${CURRENT_YEAR}/${CURRENT_MONTH}/${CURRENT_DATE}, // 创建时间 : ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}, // 功能描述 : 待补充, // , $0 ], description: 插入标准文件头注释 } }这里的变量和 Visual Studio 的宏名字不同VS Code 用的是${TM_FILENAME}、${CURRENT_YEAR}这一套含义可以参考官方变量列表。用的时候输入header再按 Tab 就插进去了。这仍然是半自动的需要手动触发。想要更接近全自动的效果VS Code 生态里有专门的文件头注释扩展装完之后可以在设置里配置模板、指定在哪些语言下自动插入、是否跳过已有注释的文件。如果你同时用 VS Code 写 Python 或者前端代码我建议直接上扩展比手写 snippet 省心。要注意的是有些扩展会在每次保存时都尝试插入如果文件里已经有注释头可能造成重复装好之后一定要看一眼它的跳过已存在头部选项。5.3 团队分发与统一管理的做法个人用和团队用是两码事。团队推广时最怕的就是每人改一遍改得还不一样。我试过两种比较靠谱的做法。一种是把改好的模板文件放进 Git 仓库里面放一个install.ps1或者.bat脚本新人克隆下来之后以管理员身份跑一次脚本脚本负责把文件拷贝到对应目录并清理缓存。脚本内容不长核心就三行拷贝文件、删除缓存目录、提示重启 IDE。这样做的好处是模板版本可追溯改了模板有 diff 可看。另一种是走自定义项模板的路线把模板打包成 zip 放到共享目录成员通过项目 → 导出模板的反向流程导入。这种方式不动安装目录权限要求低适合没有管理员权限的开发者。缺点是分发依赖每个人手动操作一次自动化程度低一些。我个人更推荐第一种因为脚本方式可以顺便把 C 的newcfile.cpp、C# 的多个项模板、甚至.editorconfig一起处理掉一次到位。.editorconfig本身不能自动加文件头但可以约束缩进、换行符、字符集这些和文件头模板配合使用代码风格的一致性会好很多。6. 常见问题排查与避坑清单改模板这件事出问题基本集中在几个固定位置。下面这张表是我这些年遇到的实际情况汇总遇到问题直接对号入座。现象最可能的原因解决办法改完模板新建文件没变化模板缓存未清关闭 IDE删除ItemTemplatesCache目录改了英文目录没效果实际生效的是中文目录确认系统语言改 2052 或 1033 对应目录中文注释变成乱码文件编码不一致保持原编码或统一为 UTF-8-BOM保存模板文件提示拒绝访问没有管理员权限以管理员身份运行编辑器$username$没被替换宏名拼写错误或位置不对对照宏表检查注意$成对出现新建 C 文件报重复定义模板里 include 与预编译头冲突模板里改用#include pch.h添加新项时直接报错模板文件被改坏用备份还原检查语法整个项模板列表消失了devenv /setup中途被强杀重新执行/setup并等待完成6.1 关于宏不被替换的排查思路宏没被替换最常见的原因是拼写错误。$safeitemname$和$safeitemrootname$只差一个root很容易写错。写错之后 Visual Studio 不会报错它会原样输出一个带$的字面量看起来就像宏失效了。所以改完模板第一件事就是新建一个文件试一下别等到写了一堆代码才发现文件头是错的。第二个原因是宏的适用场景有限。比如$rootnamespace$在 C 项模板里就没有意义因为 C 没有命名空间这个概念虽然语言有 namespace但项目层面没有 rootnamespace 这个属性。用了不支持的宏输出就会是空的或者原样字符串。判断方法很简单模板文件是哪个语言的就只用那个语言支持的宏。6.2 关于版本升级后的恢复Visual Studio 打补丁或者做修复安装时有概率把Common7\IDE下的文件刷回默认值。我遇到过两次一次是功能更新之后模板文件被重置另一次是修复安装之后 C 的newcfile.cpp变成了空白。所以我的习惯是把改好的模板文件在 Git 仓库里维护一份同时在本地也留一份备份升级完顺手对比一下。文件不大成本很低但能省掉重新摸索的时间。6.3 一些容易被忽略的细节第一注释头不要写得太长。我见过有人把文件头写了二十行包含项目简介、团队名单、联系方式、修改历史模板结果每打开一个文件都要先翻过一屏注释才能看到代码。我的经验是控制在 6 到 8 行以内必要信息有就行详细说明放在项目 README 里更合适。第二注意静态检查工具的规则。有些团队的代码检查工具会对文件头注释提出硬性要求比如必须包含版权年份、必须包含许可证标识。如果你的项目有这类工具改模板之前先确认规则要求避免改完之后批量报不符合项。这类规则通常写在检查工具的配置文件里看一眼就知道要哪些字段。第三别在模板里写死时间。有人图省事直接在模板里写死一个日期结果所有文件都是同一天创建的看起来就很假。用$year$、$month$、$day$这几个宏让它自己填才是正确姿势。第四改完之后务必用一个全新项目验证。在已有项目里测试有时候会被各种缓存干扰新建一个空项目在里面添加几个不同类型的文件看看注释头是不是都正常。这一步花两分钟能避免后面大范围返工。我个人的体会是这套改造真正值钱的地方不在于省了多少打字时间而在于它让代码规范从一件需要靠自觉的事情变成了一件由工具保证的事情。人总会偷懒工具不会。写完模板文件那一刻你就等于给整个团队加了一道理性防线后面所有的文件都会自动遵守同一个格式评审的时候也少了一个争论点。如果你还没折腾过这事找个下午花半小时搞定它回报周期短得超出想象。
返回列表