VISUAL STUDIOYA EXTENSION YAZMA – 2

ilk yazımızda temel bir extensionın nasıl oluşturulacağını ve bir extension projesinde bulunan sınıfların ne işe yaradıgını görmüştük.şimdi 1.yazımızın devamında biraz daha detaya girelim.İlk yazıda en son sağ menüye eklediğimiz custom commanddan bir tane form açılmasını sağlamıstık.
Şimdi ise tıkladıgımızın sınıfın isminide forma geçelim burada com objelerini kullanabilmemiz icin EnvDTE kütüphanesinden yararlanacağız.
Bunun için extension yazdıgımız projemize bir tane hepler class ekleyerek aşağıdaki aktif visualstudio projesinin bilgilerine erişebileceğimiz  kodumuzu yapıştırıyoruz(VisualStudioEnvironmentHelper isminde ekledim)
Bu kodlarımızın çalışması icin namespaceler ve hangi visual studio versionu icin kullanacaksanız ona göre ayar yapmanız lazım
Yani string rotEntry = String.Format(“!VisualStudio.DTE.11.0:{0}”,
Ben visual studio 2012 de yazdıgım ve çalıştıgım icin VisualStudio.DTE.11 dedim ama 2013 kullanacaksanız VisualStudio.DTE.12 demeliydiniz eğer extensionınız bir den fazla farklı visual studio ortamında çalışacaksa bu kodu kopyalıp ona göre çalışacak sekilde getcurrent metoduna if-else koymanız gerekecekti
using System;

using System.Runtime.InteropServices;

using System.Runtime.InteropServices.ComTypes;

using EnvDTE;

using Process = System.Diagnostics.Process;

namespace Skywalker.VSBilgehanPackage

{

public class VisualStudioEnvironmentHelper

{

[DllImport(“ole32.dll”)]

private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);

[DllImport(“ole32.dll”)]

private static extern void GetRunningObjectTable(int reserved,

out IRunningObjectTable prot);

internal static DTE GetCurrent()

{

//rot entry for visual studio running under current process.

string rotEntry = String.Format(“!VisualStudio.DTE.11.0:{0}”,

System.Diagnostics.Process.GetCurrentProcess().Id);

IRunningObjectTable rot;

GetRunningObjectTable(0, out rot);

IEnumMoniker enumMoniker;

rot.EnumRunning(out enumMoniker);

enumMoniker.Reset();

IntPtr fetched = IntPtr.Zero;

IMoniker[] moniker = new IMoniker[1];

while (enumMoniker.Next(1, moniker, fetched) == 0)

{

IBindCtx bindCtx;

CreateBindCtx(0, out bindCtx);

string displayName;

moniker[0].GetDisplayName(bindCtx, null, out displayName);

if (displayName == rotEntry)

{

object comObject;

rot.GetObject(moniker[0], out comObject);

return (DTE)comObject;

}

}

return null;

}

}

}
Hepler metodumuz sayesinde aktif projedeki seçili itema ulaşabiliyoruz ve bunu formumuza parametre olarak geçiyoruz

Tabi forma bu değeri parametre geçip ekranda gösterebilmek icin ufak bir modifikasyon yapıyoruz.


Tekrar start new instance extensionımızı debug modda çalıştırıp custom commanda tıkladıgımızda artık seçili classın adının ekrana geldiğini görüyoruz.
Ve son olarak bu custom commandımızın sadece belli tiplerde örneğin sadece .cs uzantılarda çıksın ancak .config uzantılarda çıkmasın gibi kısıtlamak icin aşağıdaki işlemleri yapıyoruz.

Öncelikle package projemize ProvideAutoLoad Attribute eklememiz gerekiyor

Buradaki quid UICONTEXT_SolutionExists yani solution varsa otomatik yüklenme icin guid sabiti eklememiz gerekiyor

Bu key ile alakalı detay  bilgilere msdn ulaşabilirsiniz

https://msdn.microsoft.com/en-us/library/bb166762%28v=vs.80%29.aspx

[ProvideAutoLoad(“{f1536ef8-92ec-443c-9ed7-fdadf150da82}”)]

Ayrıca burada artık örneğimizi değiştirerek menucommanddan türeyen olemenucommand nesnesi ve bunun BeforeQueryStatus eventini kullanıyor olacağız.Initialize metodumuzu aşağıdaki gibi değiştiriyoruz

protected override void Initialize()

{

Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, “Entering Initialize() of: {0}”, this.ToString()));

base.Initialize();

// Add our command handlers for menu (commands must exist in the .vsct file)

OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;

if (null != mcs)

{

// Create the command for the menu item.

CommandID menuCommandID = new CommandID(GuidList.guidVSBilgehanPackageCmdSet, (int)PkgCmdIDList.BilgehanCustomCommand);

OleMenuCommand menuItem = new OleMenuCommand(MenuItemCallback, menuCommandID);

menuItem.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus);

mcs.AddCommand(menuItem);

}

}

Ve beforeQueryStatusun kullanacağı bir handler yazayoruz.Burada ise sadece cs uzantılı dosyalarda extensionımızın aktif olacağını belirtiyoruz ve IVSHierarchy kütüphanesinden faydalanıyoruz(VsPackages proje hiyarsisi kısmını yönetebilmek icin gereklidir)

private void OnBeforeQueryStatus(object sender, EventArgs e)

{

OleMenuCommand menuCommand = sender as OleMenuCommand;

if (menuCommand != null)

{

IntPtr hierarchyPtr, selectionContainerPtr;

uint projectItemId;

IVsMultiItemSelect mis;

IVsMonitorSelection monitorSelection = (IVsMonitorSelection)Package.GetGlobalService(typeof(SVsShellMonitorSelection));

monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);

IVsHierarchy hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;

if (hierarchy != null)

{

object value;

hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_Name, out value);

if (value != null && value.ToString().EndsWith(“.cs”))

{

menuCommand.Visible = true;

}

else

{

menuCommand.Visible = false;

}

}

}

}

Ayrıca son olarak vstc filemızda dinamik visibility özelliğini aktif etmemiz gerekiyor

<CommandFlag>DefaultInvisible</CommandFlag>

<CommandFlag>DynamicVisibility</CommandFlag>

Projemizi tekrar debug modda çalıştırıp bir solution açtıgımızda artık commandımızın sadece cs uzantılı dosyalarda çıktıgını göreceğiz

Son olarak oluşturdugumuz bu extensionı başkalarının kullanabilmesi icin Release veya debug modda projemizi derleyip.vsix(Visual Studio Integration Package) olan dosyayı alıp kullanıcılarımıza veriyoruz

Kullanıcı bu vsix dosyasını kendi makinesinde çift tıklayıp kuruyor

Bunu yaptıktan sonra kullanıcımız artık açtıgı tüm projelerde bizim extensionımızı görüyor olacaktır.

Bu yazı .NET kategorisine gönderilmiş. Kalıcı bağlantıyı yer imlerinize ekleyin.

VISUAL STUDIOYA EXTENSION YAZMA – 2 için 1 cevap

  1. Murat der ki:

    Teşekkürler güzel makale

Murat için bir cevap yazın Cevabı iptal et

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Şu HTML etiketlerini ve özelliklerini kullanabilirsiniz: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>