类加载器工作机制_工作区重新加载器简介-一个Visual Studio加载项,可在重新加载项目时保存打开的文件

类加载器工作机制

类加载器工作机制

Works on my machine

A while back my buddy Sam Saffron (from Stack Overflow and Mini Profiler) complained to me on Skype that he was finding it very irritating that every time he updated his project outside of Visual Studio he would be prompted to "Reload Project" and would lose all his open files because Visual Studio would close them.

前一阵子,我的好友Sam Saffron (来自Stack OverflowMini Profiler )在Skype上向我抱怨说,他感到非常恼火,每次他在Visual Studio外部更新项目时,都会提示他“重新加载项目”,并且会失败他所有打开的文件,因为Visual Studio会关闭它们。

This apparently is becoming kind of an issue at Stack Overflow. Since they use distributed source control and often have a dozen or more folks all coding inside the same project they are integrating all the time. They'll be deep into something, update their project to test it and all their open windows close.

显然,这在Stack Overflow上已成为一个问题。 由于他们使用分布式源代码控制,并且经常有十几个或更多的人都在同一个项目中进行编码,因此他们一直在集成。 他们将深入研究某些事物,更新项目以对其进行测试,然后关闭所有打开的窗口。

It's a weird Visual Studio behavior that I've never understood. Visual Studio saves all your open files and window positions when you close the IDE and restores them when you open your solution. But when you open a project then right click and "Unload Project" you'll lose all your windows. I've reported it as a bug and it's also been voted up at User Voice, visited as a Question at StackOverflow, and a few folks have tweeted about it (The SO guys with their thumbs on the scale, no doubt) and been bugging some folks but then I got the idea to just fix it myself. It'd be a good chance to write my first Visual Studio Add-In, see if this is even possible, and fix an irritant at the same time.

这是我从未理解过的怪异的Visual Studio行为。 当您关闭IDE时,Visual Studio将保存所有打开的文件和窗口位置,并在打开解决方案时将其还原。 但是,当您打开一个项目然后右键单击并“卸载项目”时,您将丢失所有窗口。 我已经将其报告为错误,并且在User Voice上被投票在StackOverflow上被作为问题进行了访问,并且一些人在推特上发了推(毫无疑问,SO伙计们对此表示赞同)一些人,但后来我想到了自己修复的想法。 这是一个很好的机会来编写我的第一个Visual Studio加载项,看看是否有可能,同时修复刺激性。

DOWNLOAD: Workspace Reloader Visual Studio Add-in - "This package will reload the code files you had open when your project file was modified and unloaded then reloaded"

下载: Workspace Reloader Visual Studio加载项 - “此软件包将重新加载您在修改并卸载然后重新加载项目文件时打开的代码文件”

Warranty: To be clear this is the smallest of extensions. It only listens to two events and it's only 12k so you have no reason that I know of to be afraid of it. Plus, it works on my machine so you've got that going for you.

保修:需要明确的是,这是最小的扩展。 它只监听两个事件,只有12k,所以我没有理由害怕它。 另外,它可以在我的机器上运行,因此您可以轻松完成此任务。

创建一个Visual Studio扩展 (Creating a Visual Studio Extension)

Developing Visual Studio Extensions requires some patience. It's gotten a lot better with Visual Studio 2010 but back in the 2003-2005 days it was really hairy. There's a number of different kinds of things you can extend. You can add menus, add tool bars, commands, new templates, new kinds of designers and visualizers, as well as use just the shell to create your own IDE.

开发Visual Studio扩展需要一些耐心。 在Visual Studio 2010中,它变得更好了,但是在2003-2005年的日子里,它确实非常毛茸茸。 您可以扩展多种不同的功能。 您可以添加菜单,添加工具栏,命令,新模板,新型设计器和可视化器,以及仅使用外壳程序来创建自己的IDE。

I wanted to create an add-in with Zero UI. I had no need for buttons or menus, I just wanted to listen to events and act on them. I downloaded the Visual Studio 2010 SDK after reading this blog on extending Visual Studio 2010. Make sure you get the right version. I have Visual Studio 2010 SP1 so I needed the updated Visual Studio 2010 SP1 SDK.

我想用零UI创建一个加载项。 我不需要按钮或菜单,我只想听事件并对其进行操作。 在阅读了有关扩展Visual Studio 2010的博客后,我下载了Visual Studio 2010 SDK。 确保获得正确的版本。 我有Visual Studio 2010 SP1,所以我需要更新的Visual Studio 2010 SP1 SDK

File | New Project | Visual Studio Package

I made a new Visual Studio Package. This builds into a VSIX (which is just a ZIP file - isn't everything?). A VSIX has a manifest (which his just XML - isn't everything?) that you can edit in a GUI or as a text file.

我做了一个新的Visual Studio包。 这将内置到VSIX中(这只是一个ZIP文件-不是所有内容吗?)。 VSIX具有清单(可以用他的XML格式表示吗?不是全部吗?),您可以在GUI或文本文件中进行编辑。

I want my VSIX package to work on Visual Studio 11 Beta as well as Visual Studio 2010  so I added to the SupportedProducts node like this. VSIXs other than templates aren't supported in Express (I keep pushing, though):

我希望我的VSIX包可在Visual Studio 11 Beta和Visual Studio 2010上运行,因此我将这样添加到SupportedProducts节点。 Express中不支持模板以外的VSIX(不过我一直在推动):

<SupportedProducts>
<VisualStudio Version="10.0">
<Edition>Ultimate</Edition>
<Edition>Premium</Edition>
<Edition>Pro</Edition>
</VisualStudio>
<VisualStudio Version="11.0">
<Edition>Ultimate</Edition>
<Edition>Premium</Edition>
<Edition>Pro</Edition>
</VisualStudio>
</SupportedProducts>

I also setup the name, version and description in this file. 

我还在此文件中设置名称,版本和描述。

I need to decide when my package is going to get loaded. You can add one or more ProvideAutoLoad attributes to a Package class from the VSConstants class. A number of blogs posts say you need to hard code a GUID like this, but they are mistaken. There are constants available.

我需要决定何时装入包裹。 您可以从VSConstants类向Package类添加一个或多个ProvideAutoLoad属性。 许多博客文章都说您需要像这样对GUID进行硬编码,但是它们是错误的。 有可用的常数。

[ProvideAutoLoad("{ADFC4E64-0397-11D1-9F4E-00A0C911004F}")]

I can have my package automatically load in situations like these:

我可以在以下情况下自动加载我的

  • NoSolution   

    没有解决方案
  • SolutionExists

    解决方案存在
  • SolutionHasMultipleProjects   

    解决方案有多个项目
  • SolutionHasSingleProject

    解决方案有单个项目
  • SolutionBuilding

    解决方案建设
  • SolutionExistsAndNotBuildingAndNotDebugging

    解决方案存在与不建立与不调试
  • SolutionOrProjectUpgrading

    解决方案或项目升级
  • FullScreenMode

    全屏模式

For my package, I need it loaded whenever a "Solution Exists," so I'll use this Constant (in lieu of a hard coded GUID):

对于我的软件包,每当“存在解决方案”时都需要加载它,因此我将使用此常量(代替硬编码的GUID):

[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]

Next, I wanted to listen to events from the Solution like the unloading and loading of Projects. I started with the IVsSolutionsEvents interface that includes OnBefore, OnAfter and OnQuery for basically everything. Elisha has a simple listener wrapper as an answer on StackOverflow that I modified.

接下来,我想听听解决方案中的事件,例如项目的卸载和加载。 我从IVsSolutionsEvents接口开始,该接口包括OnBefore,OnAfter和OnQuery,基本上所有内容都包括在内。 Elisha有一个简单的侦听器包装,作为我修改的StackOverflow的答案

The SolutionEventsListener uses the very useful Package.GetGlobalService to get hold of the solution.

SolutionEventsListener使用非常有用的Package.GetGlobalService来获取解决方案。

IVsSolution solution = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution;
if (solution != null)
{
solution.AdviseSolutionEvents(this, out solutionEventsCookie);
}

We then sign up to hear about things that might happen to the Solution using the IVsSolutionEvents interfaces and making them look like friendly events.

然后,我们使用IVsSolutionEvents接口进行注册,以了解解决方案可能发生的事情,并使它们看起来像友好事件。

public event Action OnAfterOpenProject;
public event Action OnQueryUnloadProject;

int IVsSolutionEvents.OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded)
{
OnAfterOpenProject();
return VSConstants.S_OK;
}

int IVsSolutionEvents.OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int pfCancel)
{
OnQueryUnloadProject();
return VSConstants.S_OK;
}

I want to hear about things just before Unload happens and then act on them After projects Open. I'll save the Document Windows. There's an interface that manages Documents and Windows for the Shell called, confusingly enough IVsUIShellDocumentWindowMgr

我想听听有关卸载之前的事情,然后在项目打开之后对它们采取行动。 我将保存文档窗口。 有一个用于管理Shell的文档和Windows的接口,足以使IVsUIShellDocumentWindowMgr混乱。

I save the windows just before the unload and reopen them just after the project opens. Unfortunately these are COM interfaces so I had to pass in not an IStream but an OLE.IStream so while the ReopenDocumentWindows is easy below...

我在卸载前保存窗口,并在项目打开后重新打开它们。 不幸的是,这些是COM接口,因此我必须传递的不是IStream,而是OLE.IStream,因此,下面的ReopenDocumentWindows很容易...

listener.OnQueryUnloadProject += () =>
{
comStream = SaveDocumentWindowPositions(winmgr);
};
listener.OnAfterOpenProject += () => {
int hr = winmgr.ReopenDocumentWindows(comStream);
comStream = null;
};

The SaveDocumentWindowPositions is more complex, but basically "make a memory stream, save the documents, and seek back to the beginning of the stream."

SaveDocumentWindowPositions更为复杂,但基本上是“创建一个内存流,保存文档,然后向后寻找流的开头”。

private IStream SaveDocumentWindowPositions(IVsUIShellDocumentWindowMgr windowsMgr)
{
if (windowsMgr == null)
{
return null;
}
IStream stream;
NativeMethods.CreateStreamOnHGlobal(IntPtr.Zero, true, out stream);
if (stream == null)
{
return null;
}
int hr = windowsMgr.SaveDocumentWindowPositions(0, stream);
if (hr != VSConstants.S_OK)
{
return null;
}

// Move to the beginning of the stream with all this COM fake number crap
LARGE_INTEGER l = new LARGE_INTEGER();
ULARGE_INTEGER[] ul = new ULARGE_INTEGER[1];
ul[0] = new ULARGE_INTEGER();
l.QuadPart = 0;
//Seek to the beginning of the stream
stream.Seek(l, 0, ul);
return stream;
}

If this does it's job you'll never know it's there. You can test it by installing Workspace Reloader, opening a project and opening a few code files. Now, edit the CSProj as a text file (maybe add a space somewhere) and save it. Visual Studio should prompt you to Reload the Project. Workspace Reloader should keep your files and windows open.

如果这样做,您将永远不会知道它的存在。 您可以通过安装Workspace Reloader ,打开一个项目并打开一些代码文件来对其进行测试。 现在,将CSProj编辑为文本文件(也许在某处添加空格)并将其保存。 Visual Studio应提示您重新加载项目。 Workspace Reloader应该保持文件和窗口打开。

I hope this helps a few people. The source is here.

我希望这对一些人有帮助。 来源在这里

翻译自: https://www.hanselman.com/blog/introducing-workspace-reloader-a-visual-studio-addin-to-save-your-open-files-across-project-reloads

类加载器工作机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值