一个Visual Studio插件,在跨加载项目时保存你打开的文件

前阵子我的好友Sam Saffron(来自Stack Overflow和Mini Profiler)在 Skype上向我抱怨他发现了一件十分讨厌的事情,每次他在Visual Studio之外更新他的项目时,他都会遇到一个提示"重新加载项目",并会失去所有他已打开的文件,因为 Visual Studio 将关闭它们。

这显然在StackOverflow网站上成为一个话题。因为它们采用分布式的源控件,经常有十个或更多的人在同一项目内部编码,所以它们一直在集成。更新它们的项目来测试它时,所有打开的窗口就被关闭了。

我不能理解Visual Studio的此怪异行为。当你关闭 IDE时,Visual Studio 将保存所有打开的文件和窗口的位置,并当你打开你的解决方案时,VS会还原它们。 但当你打开一个项目,然后右击“卸载项目”,你就会失去所有的窗口。我已经就此报告了一个bug ,这一问题在用户心声网站上也被指出来了,在StackOverflow上也被提问到了,还有人在 twitter 上讨论此(如此多的人,毫无疑问),此问题正在折磨着一些人,然后我就想着自己修复它。这正是编写我的第一个Visual Studio插件的好机会,看看是否可能,同时也修复一个令人讨厌的东西。

下载:Workspace Reloader Visual Studio 插件 - "当你的项目文件被修改,卸载,然后重新加载时,此软件包将会重新加载打开的代码文件。

保证书:说清楚一点,这是最小的扩展。它只监听两个事件,只有 12 k,所以你没有任何理由害怕它。另外,它在我的机器上能正常运行,所以到你了。

创建一个 Visual Studio 扩展

开发 Visual Studio 扩展需要一些耐心。使用Visual Studio 2010 开发扩展变得越来越好了,但早在 2003 到2005 年,真的是很令人沮丧。你可以扩展不同类别的东西。你可以添加菜单, 添加工具条、 命令、 新的模板、新类别的设计器和可视化工具,以及使用shell来创建你自己的 IDE。

我想要创建一个无UI的插件。我不需要按钮或菜单,我只想要监听事件,并操作它们。在我读了这篇关于扩展 Visual Studio 2010的博客之后,我下载了 Visual Studio 2010 SDK。请确保下载正确的版本。因为我已经安装了 Visual Studio 2010 SP1,所以我需要更新 Visual Studio 2010 SP1 SDK.

我做了一个新的 Visual Studio 软件包。它编译成一个 VSIX文件 (这只是一个 ZIP 文件-并不是别的?)。VSIX 有一个清单 (这只是一个 XML-并不是别的?),你可以在 GUI 中编辑或作为文本文件。

我想要将我的 VSIX 包与Visual Studio 11 beta 版以及 Visual Studio 2010 一起使用,所以我添加到像这样的 SupportedProducts 节点。VSIXs 以外其他模板在Express中不受支持(虽然我一直努力):

1: <SupportedProducts> 2: <VisualStudio Version="10.0"> 3: <Edition>Ultimate</Edition> 4: <Edition>Premium</Edition> 5: <Edition>Pro</Edition> 6: </VisualStudio> 7: <VisualStudio Version="11.0"> 8: <Edition>Ultimate</Edition> 9: <Edition>Premium</Edition> 10: <Edition>Pro</Edition> 11: </VisualStudio> 12: </SupportedProducts>

我也在此文件中设置名称、 版本和说明。

我需要决定何时加载我的软件包。你可以添加一个或多个ProvideAutoLoad属性到来自VSConstants类的Package类中。很多博客帖子说你需要像这样硬编码一个GUID,但他们错了。有可用的常数。

[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]

我可以在像这样的情况下自动加载软件包:

NoSolution SolutionExists SolutionHasMultipleProjects SolutionHasSingleProject SolutionBuilding SolutionExistsAndNotBuildingAndNotDebugging SolutionOrProjectUpgrading FullScreenMode

至于我的软件包,只要任何时候“存在解决方案”,我就需要加载它",所以我将使用此常量 (代替硬编码GUID):

[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]

接下来,我想要监听解决方案中像卸载和加载项目的事件。我从IVsSolutionsEvents接口入手,它包括 OnBefore、 OnAfter 和 OnQuery。Elisha在StackOverflow上有一个简单的侦听器包装器,作为接听的用途。

SolutionEventsListener 使用Package.GetGlobalService 来掌握解决方案。

1: IVsSolution solution = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution; 2: if (solution != null) 3: { 4: solution.AdviseSolutionEvents(this, out solutionEvents
Cookie); 5: }

通过使用 IVsSolutionEvents 接口,并让它们看起来像友好的事件,然后我们注册来倾听可能发生在解决方案中的事情。

1: public event Action OnAfterOpenProject; 2: public event Action OnQueryUnloadProject; 3:  4: int IVsSolutionEvents.OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded) 5: { 6: OnAfterOpenProject(); 7: return VSConstants.S_OK; 8: } 9:  10: int IVsSolutionEvents.OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int pfCancel) 11: { 12: OnQueryUnloadProject(); 13: return VSConstants.S_OK; 14: }

我想监听卸载发生之前的事情,然后在打开项目之后执行它们。我将保存文档窗口。有一个管理Shell所调用的文档和窗口的接口, IVsUIShellDocumentWindowMgr.

我在卸载之前保存这些窗口,并在打开该项目之后重新打开它们。不幸的是这些是 COM 接口,所以我不得不在OLE. Istream中传递而不是IStream ,虽然下面的 ReopenDocumentWindows是很容易...

1: listener.OnQueryUnloadProject += () => 2: { 3: comStream = SaveDocumentWindowPositions(winmgr); 4: }; 5: listener.OnAfterOpenProject += () => 6: { 7: int hr = winmgr.ReopenDocumentWindows(comStream); 8: comStream = null; 9: };

SaveDocumentWindowPositions更加复杂,但基本上是"制作内存流,保存文档,然后寻回到流的起始点"。

1: private IStream SaveDocumentWindowPositions(IVsUIShellDocumentWindowMgr windowsMgr) 2: { 3: if (windowsMgr == null) 4: { 5: return null; 6: } 7: IStream stream; 8: NativeMethods.CreateStreamOnHGlobal(IntPtr.Zero, true, out stream); 9: if (stream == null) 10: { 11: return null; 12: } 13: int hr = windowsMgr.SaveDocumentWindowPositions(0, stream); 14: if (hr != VSConstants.S_OK)

时间: 2024-12-29 18:05:35

一个Visual Studio插件,在跨加载项目时保存你打开的文件的相关文章

关于vs2012无法加载项目的问题

问题描述 关于vs2012无法加载项目的问题 vs2012打开项目时报错,提示"未能加载项目,根级别上的数据无效,第1行,位置1.C:Program FilesMSBuild4.0Microsoft.Common.TargetsImportAfterDesktop_1.ini". 但是当我删除.csproj文件中的 <Import Project="$(MSBuildToolsPath)Microsoft.CSharp.targets" />时,他是可以

Visual Basic .NET 中动态加载类(一)

visual|动态|加载 Visual Basic .NET 中动态加载类 · ··Microsoft 摘要:理想情况下,编写软件系统之前我们就应该知道此软件系统需要完成哪些操作.但实际情况并非如此,因此我们的系统应该是可以调整的. 最能体现这种适应性的是动态集成新功能的能力.例如,在 Windows 窗体应用程序中,这种能力是指加载编译原始应用绦蚝芫靡院蟠唇ǖ拇疤宓哪芰Α?/P> 这种操作在 Microsoft Visual Basic 6.0 中几乎是不可能的,但是在 Visual Basi

Android Studio NDK开发同时加载多个SO文件时该如何配置

问题描述 Android Studio NDK开发同时加载多个SO文件时该如何配置 使用AS学习NDK开发时,当DEMO中只用到一个SO文件,开发.调试均正常. AS在开发NDK时是不需要手动编写Android.mk和Application.mk的,而通过配置build.gradle文件,可以自动在build目录下生成Android.mk,但是在配置build.gradle文件时,发现在ndk{...}中,只能配置一个moduleName,而这个moduleName正是编译后生成的SO文件名,请

ReSharper 6发布 智能化微软Visual Studio插件

ReSharper 6更新日志: Rich support for JavaScript, CSS, and ASP.NET MVC 3 Razor view engine including code inspections, navigation and usage search, and extended code completion. Navigation and search improved with new features and usability enhancements.

ReSharper 6.0 Beta 2发布 智能化微软Visual Studio插件

无庸置疑,ReSharper是最智能化的微软Visual Studio插件.它包括一系列丰富的能大大增加C#和Visual http://www.aliyun.com/zixun/aggregation/11183.html">Basic.net开发者生产力的特征.使用ReSharper,你可以进行深度代码分析,智能代码协助,实时错误代码高亮显示,解决方案范围内代码分析,快速代码更正,一步完成代码格式化和清理,业界领先的自动代码重构,高级的集成单元测试方案,和强大的解决方案内导航和搜索.实

Win8系统Flash插件无法自动加载怎么解决?

  Win8系统Flash插件无法自动加载怎么解决? 一.按住键盘Win+A+X键打开Windows命令提示符,然后在命令提示符窗口上输入cd C:WindowsSystem32MacromedFlash命令,再回车. 二.接着在命令提示符窗口上输入regsvr32 Flash.ocx命令,再回车.接着在命令提示符窗口上输入cd C:WindowsSysWOW64MacromedFlash命令. 三.然后在Win8系统命令提示符窗口中输入regsvr32 Flash.ocx命令,再回车,接着系统

加载列表时jquery获取ul中第一个li的属性_jquery

当加载列表时,默认希望选中第一条.top_menu 为ul的ID 通过 $("#top_menu li:first") 就可以获取到 ul下第一个li标签.然后就可以利用 例如 修改属性:$("#top_menu li:first").attr("class","select"); 触发事件:$("#top_menu li:first").click(); 如果想获取li下的 a标签,如下: $("

安卓frgment-Frgment切换到另一个Frgement 在返回 数据重写加载 怎么让他只加载一次!

问题描述 Frgment切换到另一个Frgement 在返回 数据重写加载 怎么让他只加载一次! Frgment切换到另一个Frgement 在返回 数据重写加载 怎么让他只加载一次! 解决方案 frgment 加载数据 解决方案二: 加上一个全局变量判断下

2012 ++ 32-VS无法加载项目,未能正确加载解决方案中的一个或多个项目,有关详细信息,请参见“输出”窗口

问题描述 VS无法加载项目,未能正确加载解决方案中的一个或多个项目,有关详细信息,请参见"输出"窗口 输出窗口显示:无法加载项目文件 我的工程在自己电脑里能打开,要拿到其他电脑运行不能加载,项目加载失败.同样是VS2012,求解决办法. 解决方案 如果不能保证用户电脑上安装相同版本cuda,那么试试在引用的dll属性里面复制到本地项选TRUE,这样在编译的时候,相应的dll文件会输出到程序文件夹,在运行的时候,后先搜索这个dll调用. 解决方案二: 检查一下你的项目是否引用了等三方类库