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下的文件同步软件,可以跨服务器运行,第一次运行的时候是全部备份同步,之后的同步采用的是增量同步 这个软件分为服务端和客户端. 服务器是需要同步的文件源, 客户端相当于是备 ...
随机推荐
- HDU 1426 dancing links解决数独问题
题目大意: 这是一个最简单的数独填充题目,题目保证只能产生一种数独,所以这里的初始9宫格较为稠密,可以直接dfs也没有问题 但最近练习dancing links,这类数据结构解决数独无疑效率会高很多 ...
- mappedBy的作用
mappedBy的意思就是"被映射",即mappedBy这方不用管关联关系,关联关系交给另一方处理 1.规律:凡是双向关联,mapped必设,因为根本都没必要在2个表中都存在一个外 ...
- 匈牙利游戏(codevs 1269)
题目描述 Description Welcome to the Hungary Games! The streets of Budapest form a twisted network of one ...
- HDU 6070 (线段树)(统计颜色)
HDU 6070 Partition Problem : 给一段长度为n的序列,要求找出一段区间,使得这段区间的数字种类除以区间长度最小.输出最后的答案即可.(n <= 60000)(9s时限) ...
- as3corelib Tutorial:How to Use ArrayUtil Class in Flex
ArrayUtil class contains static utility methods for manipulating and working with Arrays. Note that ...
- [Bzoj1767][Ceoi2009]harbingers (树上斜率优化)
1767: [Ceoi2009]harbingers Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 451 Solved: 120[Submit][S ...
- AtCoder Regular Contest 091&092
091E(构造) 题意: 给出n,a,b.你需要构造出一个长度为n的n的排列,其中最长上升子序列的长度为a,最长下降子序列的长度为b. n,a,,b<=3e5 分析: 我们可以构造出这样的数列, ...
- ArcGIS10.x Engine直连提示连接超时ORA-12170 来自:http://www.iarcgis.com/?p=1004
导语 随着Esri大力宣传直连,用户也越来越由服务连接,改为直连,当然ArcGIS Engine开发用户也不例外. 环境 Oracle数据库,ArcGIS版本不限,不过由于9版本多以服务连接,以10版 ...
- HDU 4786 Fibonacci Tree(生成树,YY乱搞)
http://acm.hdu.edu.cn/showproblem.php? pid=4786 Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others ...
- IOS开发 ios7适配
ios7控制器试图默认为全屏显示,导航栏的不同设置会产生不同的效果. 首先判断系统的的版本,区别: if (floor(NSFoundationVersionNumber) <= NSFound ...