VS2013文件同步插件开发
一、插件功能描述
插件监控一个xml文件,当该文档有添加新元素在保存的时候将新增的元素同步到指定的目录下。
二、模板的选择
由于该功能是跟代码编辑有关的,要监控文档的保存事件,所以要在文档打开的时候就注册保存事件的响应方法。VS提供了一个接口,监听文档的打开事件,这个接口就是:IWpfTextViewCreationListener,接口代码如下,该接口只有一个方法,在文档打开的时候会调用TextViewCreated方法执行。
// 摘要:
// Listens to text view created events.
public interface IWpfTextViewCreationListener
{
// 摘要:
// Called when a text view having matching roles is created over a text data
// model having a matching content type.
//
// 参数:
// textView:
// The newly created text view.
void TextViewCreated(IWpfTextView textView);
}
所以随便选择一个模板都是可以的,只要在项目里面将模板创建的插件入口类改为继承IWpfTextViewCreationListener接口,并实现其接口即可。由于该功能需要用到选项配置功能,所以我建议读者使用Visual Stuido Package模板,因为使用该模板添加选项页会比较容易。这是msdn上在使用Visual Studio Package模板的情况下如何添加选项页的教程:http://msdn.microsoft.com/en-us/library/bb166195.aspx。我选择的是Editor Text Adornment模板,因为该模板创建的入口类就是继承IWpfTextViewCreationListener接口,但是使用该模板的话,添加选项页会比较麻烦一点。
三、添加选项页
按照msdn上的教程,我们知道需要添加两个类:继承Package的类和继承DialogPage的类,过程我就不再赘述。如果紧紧按照msdn上的教程,你会发现在工具-选项下根本没有我们添加的选项页(非Visual Studio Package模板的情况),这是为什么呢?原来在我们的csproj文件和source.extension.vsixmanifest里缺少了一些元素,按照下面的步骤就可以实现添加选项页的功能:
1、打开source.extension.vsixmanifest,选择Assets选项,点击New按钮,弹出图-1窗口
图-1
Type选择Microsoft.VisualStudio.Assembly,Source选择A project in current solution,Project选择当前的插件项目,点击OK添加完成,再次点击New按钮,这次的Type选择Microsoft.VisualStudio.VsPackage,Source和Project跟第一次的一样即可。
2、将csproj文件里的GeneratePkgDefFile元素改为true。
3、GeneratePkgDefFile元素后添加<CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
4、在GeneratePkgDefFile元素前添加<IncludeAssemblyInVSIXContainer>true</IncludeAssemblyInVSIXContainer>,注意IncludeAssemblyInVSIXContainer这个元素一定要添加在GeneratePkgDefFile和CopyBuildOutputToOutputDirectory元素之前。
经过上面的四个步骤,我们添加的选项页就会显示在工具-选项里了,如果缺少了第一个步骤的话会出现”加载此属性页时出错“的错误。
四、监听保存事件
通过查看TextViewCreated函数的参数类型textView,可以知道IWpfTextView 接口并没有包含文档保存的事件。那么,我们该如何才能订阅保存事件呢?通过查找相关的资料,发现可以通过以下方式获取文档的保存事件:
//EnvDTE.DTE _dte
this._dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
//EnvDTE.Events _events
this._events = this._dte.Events;
//EnvDTE.DocumentEvents _docEvents
this._docEvents = this._events.DocumentEvents;
一定要记住一定要将上面的三个对象定义为全局变量,否则就没办法响应保存事件,这是因为C#的垃圾回收机制造成的,读者可以自己试一下定义为局部变量的情况。
以下是该插件的部分代码
namespace AppSettingsSync
{
public class TextViewListener
{
/// <summary>
/// 文档信息
/// </summary>
private ITextView _view; private DTE _dte;
private Events _events;
private DocumentEvents _docEvents;
/// <summary>
/// 文档是否修改过
/// </summary>
private bool _isChanged;
/// <summary>
/// 保存的时候是否自动同步到其他AppSettings.xml
/// </summary>
private bool _isAutoReplace = true;
/// <summary>
/// 触发同步操作的AppSetting.xml
/// </summary>
private string _sourceFile;
/// <summary>
/// 要被同步的AppSettings.xml所在的文件目录
/// </summary>
private string _targetFolder; /// <summary>
/// 打开文档时触发
/// </summary>
/// <param name="textView"></param>
public TextViewListener(IWpfTextView textView)
{
this._view = textView;
this._dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
Properties props = this._dte.get_Properties("IStrong", "AppSettingsSync");
if (props == null)
return;
this._sourceFile = (string)props.Item("SourceXmlFilePath").Value;
//File.AppendAllText(@"D:\log.txt", "源文件" + this._sourceFile + "当前文件" + this._dte.ActiveDocument.FullName);
if (!this._dte.ActiveDocument.FullName.Equals(this._sourceFile, StringComparison.OrdinalIgnoreCase))
return;
//获取DTE对象
this._events = this._dte.Events;
this._docEvents = this._events.DocumentEvents;
//订阅文档保存和修改事件
this._docEvents.DocumentSaved += _docEvents_DocumentSaved;
this._view.TextBuffer.Changed += TextBuffer_Changed;
} /// <summary>
/// 文档修改事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void TextBuffer_Changed(object sender, Microsoft.VisualStudio.Text.TextContentChangedEventArgs e)
{
if (e.Changes.Count() > )
this._isChanged = true;
} /// <summary>
/// 文档保存事件
/// </summary>
/// <param name="Document"></param>
async void _docEvents_DocumentSaved(Document Document)
{
try
{
//File.AppendAllText(@"D:\log.txt", "触发保存事件");
//获取Tool->Opetions->IStrong->AppSettingsSync配置项内容
Properties props = this._dte.get_Properties("IStrong", "AppSettingsSync");
if (props == null)
return;
this._sourceFile = (string)props.Item("SourceXmlFilePath").Value;
//保存时要同时满足是源AppSettings.xml文件和该文件有被修改过
if (Document.FullName.Equals(this._sourceFile, StringComparison.OrdinalIgnoreCase) && this._isChanged)
{
this._isAutoReplace = (bool)props.Item("IsAutoSync").Value;
this._targetFolder = (string)props.Item("TargetFolder").Value;
//手动选择要同步的文件
if (!this._isAutoReplace)
{
SelectFiles sf = new SelectFiles(this._sourceFile, this._targetFolder);
sf.ShowDialog();
this._isChanged = false;
}
else
{
//自动同步文件
string fileName = System.IO.Path.GetFileName(this._sourceFile);
string[] files = Directory.GetFiles(this._targetFolder, fileName, SearchOption.AllDirectories);
this._isChanged = false;
await SyncHelper.SyncAppSettings(this._sourceFile, files);
//同步完成后修改Visual Studio状态栏信息
IVsStatusbar bar = ServiceProvider.GlobalProvider.GetService(typeof(SVsStatusbar)) as IVsStatusbar;
bar.SetText("AppSettings配置文件同步完成。");
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "提示", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
获取VS的主题颜色
/// <summary>
/// 将模态窗口的颜色设置为Visual Studio的背景色
/// </summary>
/// <param name="themeColor"></param>
/// <returns></returns>
private Color converVsThemeColor(vsThemeColors themeColor)
{
DTE2 dte2 = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.
GetActiveObject("VisualStudio.DTE.12.0");
uint color = dte2.GetThemeColor(themeColor);
int a = (int)color / 0x1000000;
int b = (int)(color - a * 0x1000000) / 0x10000;
int g = (int)(color - a * 0x1000000 - b * 0x10000) / 0x100;
int r = (int)(color - a * 0x1000000 - b * 0x10000 - g * 0x100);
return Color.FromArgb(0xFF, r, g, b);
}
VS2013文件同步插件开发的更多相关文章
- BAT实现服务器文件同步
服务器文件同步有很多工具,例如 GoodSync.rsync.BitTorrent Sync等……其实WINDOWS下自带了一个文件同步利器:ROBOCOPY.它是一个命令行的目录复制命令,自从Win ...
- 使用syncthing进行双机文件同步
使用syncthing进行双机文件同步 syncthing是一款开源的文件同步软件,可以 syncthing安装 tar -zxvf syncthing-linux-amd64-v0.12.15.ta ...
- sharepoint多个NLB的web前段如何进行文件同步?
大家都知道,sharepoint2010服务器场可能有2个或2个以上的web服务器做NLB,有个时候牵涉到上传文件到文件夹(说到这里,有人会说全部以二进制文件保存到文档库啊,但是有些情况不允许的,比如 ...
- BitTorrent Sync - 神奇的文件同步软件,无需服务器让多台电脑互相同步!
176,487 微博 腾讯 空间 微信 141 49 如今人们对文件备份和同步的需求已经越来越强烈了.像 Dropbox 一样的云存储网盘有很多,但它们都有一个局限性,就是所有的文件都得经过它们的服务 ...
- 烂泥:linux文件同步之rsync学习(一)
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 这几天刚好有空就打算开始学习linux下的文件同步软件rsync,在学习rsync时,我们可以分以下几个步骤进行: 1. rsync是什么 2. rsy ...
- CentOS系统rsync文件同步 安装配置
rsync是类unix系统下的数据镜像备份工具,从软件的命名上就可以看出来了——remote sync 它的特性如下: 可以镜像保存整个目录树和文件系统. 可以很容易做到保持原来文件的权限.时间.软硬 ...
- inotify配合rsync实现文件同步
一.slave端rsync设置在此部署rsync服务和rsync daemon 1.安装rsync 2.配置rsyncd.conf文件#vi /etc/rsyncd.conf配置文件uid = r ...
- Rsync 3.1.0 发布,文件同步工具
文件同步工具Rsync 3.1.0发布.2013-09-29 上一个版本还是2011-09-23的3.0.9 过了2年多.Rsync基本是Linux上文件同步的标准了,也可以和inotify配合做实时 ...
- cwRsync window下的跨服务器的文件同步
cwRsync 是window下的文件同步软件,可以跨服务器运行,第一次运行的时候是全部备份同步,之后的同步采用的是增量同步 这个软件分为服务端和客户端. 服务器是需要同步的文件源, 客户端相当于是备 ...
随机推荐
- 什么是TLS?
最近在Istio实验中经常遇到HTTP,HTTPS,TLS等名词,感觉忘得差不多,需要复习一下计算机网络的知识了. 本文参考 http://www.techug.com/post/https-ss ...
- CodeForces230A
题目大意: 一个打恐龙的游戏,有初始体力s,和恐龙n只,然后输入n只恐龙的体力xi,和击杀它得到的奖励体力yi,只有自身体力大于恐龙体力时才能进行击杀,击杀恐龙的顺序可以不定 这题运用到了贪心的思想, ...
- bzoj 1701 [Usaco2007 Jan]Cow School牛学校
[Usaco2007 Jan]Cow School牛学校 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 175 Solved: 83[Submit][S ...
- C#.net中当地址有中文时,图片无法显示解决方法
原文发布时间为:2008-11-05 -- 来源于本人的百度文章 [由搬家工具导入] 搞了半天都无法正常显示图片, string path = Server.MapPath("." ...
- 新建一个基于vue.js+Mint UI的项目
上篇文章里面讲到如何新建一个基于vue,js的项目(详细文章请戳用Vue创建一个新的项目). 该项目如果需要组件等都需要自己去写,今天就学习一下如何新建一个基于vue.js+Mint UI的项目,直接 ...
- HDU 4651 (生成函数)
HDU 4651 Partition Problem : n的整数划分方案数.(n <= 100008) Solution : 参考资料: 五角数 欧拉函数 五边形数定理 整数划分 一份详细的题 ...
- msp430入门编程34
msp430中C语言的可移植--消除硬件差异
- 介绍 JSON的
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Lan ...
- php 之mysql安全
php 之mysql安全 原文:https://www.cnblogs.com/mafeng/p/5939329.html. 请浏览原文. 一.服务器配置方面. (1) 打开php的安全模式 php的 ...
- poj3532求生成树中最大权与最小权只差最小的生成树+hoj1598俩个点之间的最大权与最小权只差最小的路经。
该题是最小生成树问题变通活用,表示自己开始没有想到该算法:先将所有边按权重排序,然后枚举最小边,求最小生成树(一个简单图的最小生成树的最大权是所有生成树中最大权最小的,这个容易理解,所以每次取最小边, ...