为 Visual Studio 2010 开发扩展插件
之前看到有国外的大神开发了一些非常好玩的 Visual Studio 扩展插件,觉得非常有意思,自己也参考了别人的代码做了一个插件。
首先需要安装 Visual Studio SDK ,安装不需要其它的工具就可以,直接使用 Visual Studio 安装包。
安装完成后打开 Visual Studio 2010,创建一个名为 VSEditorBackgroud 的 VSIX Project:文件(File)-> 新建(New)-> 项目(Project)->Visual C#->Extensibility-> VSIX Project,名称为 VSEditorBackgroud。
添加 Config 类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Serialization; using System.IO; namespace VSEditorBackgroud { [Serializable] public class Config { public ImageConfig BackgroundImage; private static Config _Config = null ; [XmlAttribute] public double LayerOpacity; private static object staticSyncRoot = new object (); public Config() { this .LayerOpacity = 0.5; this .BackgroundImage = new ImageConfig(); } public static Config CreatePure() { Config config = new Config(); return config; } public static Config CurrentConfig { get { lock (staticSyncRoot) { XmlSerializer serializer = new XmlSerializer( typeof (Config), new XmlRootAttribute( "ImageConfig" )); bool IsCreate = false ; if (_Config == null ) { if (File.Exists(ConfigConsts.ConfigPath)) { try { using (StreamReader reader = new StreamReader(ConfigConsts.ConfigPath)) { _Config = (Config)serializer.Deserialize(reader); } IsCreate = true ; } catch { } } if (!IsCreate) { _Config = CreatePure(); try { using (StreamWriter writer = new StreamWriter(ConfigConsts.ConfigPath, false , ConfigConsts.NoBomUTF8)) { serializer.Serialize(writer, _Config, ConfigConsts.VoidNamespaceMapping); } } catch { } } } } return _Config; } } [Serializable] public class ImageConfig { [XmlAttribute] public double Opacity = 1.0; public string Uri = "\t" ; } } } |
添加 ConfigConsts 类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Threading; using System.Xml.Serialization; namespace VSEditorBackgroud { internal static class ConfigConsts { public static readonly string ConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\Visual Studio 2010\\Settings" , "VSEditorBackgroud.config" ); private static Encoding nobomutf8; public static Encoding NoBomUTF8 { get { if (nobomutf8 == null ) { Interlocked.CompareExchange<Encoding>( ref nobomutf8, new UTF8Encoding( false ), null ); } return nobomutf8; } } public static XmlSerializerNamespaces VoidNamespaceMapping { get { XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); namespaces.Add( "" , "" ); return namespaces; } } } } |
编辑器背景类 EditorBackgroud:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | using System.Windows.Controls; using System.Windows.Media; using Microsoft.VisualStudio.Text.Editor; using System.Windows.Media.Imaging; using System; namespace VSEditorBackgroud { /// <summary> /// Adornment class that draws a square box in the top right hand corner of the viewport /// </summary> public class EditorBackgroud { private Image _image; private IWpfTextView _view; private IAdornmentLayer _adornmentLayer; /// <summary> /// Creates a square image and attaches an event handler to the layout changed event that /// adds the the square in the upper right-hand corner of the TextView via the adornment layer /// </summary> /// <param name="view">The <see cref="IWpfTextView"/> upon which the adornment will be drawn</param> public EditorBackgroud(IWpfTextView view) { _view = view; Config _Config = Config.CurrentConfig; //Grab a reference to the adornment layer that this adornment should be added to _adornmentLayer = view.GetAdornmentLayer( "VSEditorBackgroud" ); _adornmentLayer.Opacity = _Config.LayerOpacity; ApplyImageConfig(_Config.BackgroundImage); _view.ViewportHeightChanged += delegate { this .onSizeChange(); }; _view.ViewportWidthChanged += delegate { this .onSizeChange(); }; } private void ApplyImageConfig(Config.ImageConfig config) { if (config != null ) { try { Image image = new Image(); string uri = config.Uri; BitmapImage bgImage = new BitmapImage(); bgImage.BeginInit(); bgImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache; bgImage.CacheOption = BitmapCacheOption.OnLoad; bgImage.UriSource = new Uri(uri); bgImage.EndInit(); image.Stretch = Stretch.Fill; image.Opacity = config.Opacity; image.Source = bgImage; this ._image = image; } catch { } } } public void onSizeChange() { //clear the adornment layer of previous adornments _adornmentLayer.RemoveAllAdornments(); if ( this ._image != null && ! this ._image.Width.Equals( this ._view.ViewportWidth)) this ._image.Width = this ._view.ViewportWidth; if ( this ._image != null && ! this ._image.Height.Equals( this ._view.ViewportHeight)) this ._image.Height = this ._view.ViewportHeight; //Place the image in the top right hand corner of the Viewport Canvas.SetLeft(_image, _view.ViewportLeft); Canvas.SetTop(_image, _view.ViewportTop); //add the image to the adornment layer and make it relative to the viewport _adornmentLayer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative, null , null , _image, null ); } } } |
EditorFactory 类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | using System.ComponentModel.Composition; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Utilities; namespace VSEditorBackgroud { #region Adornment Factory /// <summary> /// Establishes an <see cref="IAdornmentLayer"/> to place the adornment on and exports the <see cref="IWpfTextViewCreationListener"/> /// that instantiates the adornment on the event of a <see cref="IWpfTextView"/>'s creation /// </summary> [Export( typeof (IWpfTextViewCreationListener))] [ContentType( "text" )] [TextViewRole(PredefinedTextViewRoles.Document)] internal sealed class PurpleBoxAdornmentFactory : IWpfTextViewCreationListener { /// <summary> /// Defines the adornment layer for the scarlet adornment. This layer is ordered /// after the selection layer in the Z-order /// </summary> [Export( typeof (AdornmentLayerDefinition))] [Name( "VSEditorBackgroud" )] [Order(After = PredefinedAdornmentLayers.Outlining)] [TextViewRole(PredefinedTextViewRoles.Document)] public AdornmentLayerDefinition editorAdornmentLayer = null ; /// <summary> /// Instantiates a Wen manager when a textView is created. /// </summary> /// <param name="textView">The <see cref="IWpfTextView"/> upon which the adornment should be placed</param> public void TextViewCreated(IWpfTextView textView) { new EditorBackgroud(textView); } } #endregion //Adornment Factory } |
修改 source.extension.vsixmanifest 文件的信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <?xml version= "1.0" encoding= "utf-8" ?> <Vsix xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd= "http://www.w3.org/2001/XMLSchema" Version= "1.0.0" xmlns= "http://schemas.microsoft.com/developer/vsx-schema/2010" > <Identifier Id= "3f2ce087-8d13-492c-a207-e1fdbfd1cf58" > <Name>VSEditorBackgroud</Name> <Author>Charles Zhang</Author> <Version>1.0.0.5</Version> <Description xml:space= "preserve" >The Visual Studio Editor Backgroud plugin. </Description> <Locale>4</Locale> <License>license.rtf</License> <Icon>icon.ico</Icon> <PreviewImage>PreviewImage.jpg</PreviewImage> <SupportedProducts> <VisualStudio Version= "10.0" > <Edition>Ultimate</Edition> <Edition>Premium</Edition> <Edition>Pro</Edition> <Edition>Express_All</Edition> </VisualStudio> <VisualStudio Version= "11.0" > <Edition>Ultimate</Edition> <Edition>Premium</Edition> <Edition>Pro</Edition> <Edition>Express_All</Edition> </VisualStudio> </SupportedProducts> <SupportedFrameworkRuntimeEdition MinVersion= "4.0" MaxVersion= "4.5" /> </Identifier> <References /> <Content> <MefComponent>|%CurrentProject%|</MefComponent> </Content> </Vsix> |
在项目中添加一个 PreviewImage.jpg 用做插件的预览图,添加 icon.ico 用做扩展的图标。
编译项目,安装生成的 Vsix 文件。
安装好以后在扩展管理器中的效果如下:
编辑器的效果如下:
以上就是 Visual Studio 2010 开发扩展插件的过程了。
分类:
DotNet
标签:
Visual Studio
, C#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架