VSTA 2019:如何获知二进制状态并从宿主应用触发源码编译
VSTA 2019 集成核心问题实操解法
问题1:重编译完成时机判定与新程序集加载逻辑
- 首先明确现有用到的事件的触发边界:
BinaryItemsChanged的触发节点是旧二进制程序集被标记失效、文件被编译进程占用的时刻,确实不代表新程序集已完成生成。ProjectChanged、ProjectChangeCommitted仅追踪源码文本编辑、项目引用变更的动作,完全不关联编译输出的全流程节点,因此不会在编译完成时触发。
- 宿主侧可靠的时机判定方案:
VSTA 2019公开接口未提供原生的“编译完成”事件,可通过两种无侵入方式实现精准判定:- 优先通过宿主持有的
IVsaCompilerHost接口,绑定C#编译流程的收尾回调——该回调在新程序集完全写入磁盘、文件句柄释放后触发,不存在加载到半程的文件锁问题。 - 兜底方案直接监控VSTA项目输出路径下的目标程序集文件状态:当文件从被编译进程独占锁定、变为可被其他进程正常读取时,即为新程序集生成完成的可靠节点。
- 优先通过宿主持有的
- 加载流程优化注意事项:
不要在BinaryItemsChanged触发时立刻卸载旧程序集,否则会出现短暂的功能空窗期;正确流程是BinaryItemsChanged仅标记待替换状态,等新程序集写盘完成后,一次性完成旧程序集卸载、新程序集加载的全流程。
问题2:无VSTA编辑器介入的全自动宏流程实现
结论:完全可以实现全程不打开VSTA编辑器、宏录制完成即可直接使用的效果。
- 编译流程触发方法:
VSTA 2019宿主侧持有的IApplication接口直接暴露了Build()方法,无需唤起编辑器界面,即可在宏录制完成、生成的C#代码写入VSTA项目指定方法后,直接调用该方法触发和编辑器内手动点“生成”完全一致的完整编译流程,覆盖语法校验、引用解析、程序集输出全环节。 - 体验优化适配点:
- 调用
Build()后需同步获取编译返回结果:若存在语法错误,直接在宿主应用UI侧展示结构化的错误清单,将错误位置、问题描述和宏录制时的操作节点做映射,让用户在宿主侧即可完成修正,无需跳转至VSTA界面。 - 编译流程完成后,直接复用前述的新程序集状态判定逻辑,完成新宏功能的加载,实现录制完成即可调用的效果。
- 注意不要依赖VSTA的默认后台隐式编译能力:该能力仅用于编辑器内的语法提示,不会生成可被宿主加载的可执行输出程序集,必须显式调用
Build()方法才能生成有效二进制。
- 调用
内容的提问来源于stack exchange,提问作者Maurikke
相关产品推荐
相关产品推荐

