29 Aralık 2008 Pazartesi

VS2008'de Custom Project Template Oluşturmak

VS2008'de yeni proje açarken veya add new item ile yeni item eklerken her zaman kullandığımız ortak bir template oluşturmak isteyebiliriz. Ben project template için yaptım ama item template'in de bir farkı yok.

Bu konuda pek yapılmış bir örnek bulamamıştım. Bu yüzden bütün adımları anlatmaya çalışacağım.

Öncelikle template dosyamızı oluşturuyoruz. Bunun için bir class library projesi açıyor ve template dosyasını istediğimiz özelliklere göre oluşturuyoruz.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class $myproperty$
{
}






Finish'e basarak template oluşturma işlemini bitiriyoruz. Oluşan template zip dosyası Belgelerim/Visual Studio 2008/My Exported Templates ve Belgelerim/Visual Studio 2008/Templates/ProjectTemplates altında oluşacaktır. Biz işlemleri ProjectTemplates altındaki dosyada yapacağız.
Şimdi, yeni bir class library projesi daha açalım ve aşağıdaki dll'leri ekleyelim.
  • EnvDTE
  • Microsoft.VisualStudio.TemplateWizardInterface
Ben proje oluşturulduğunda  bir form açılmasını istediğim için projeye bir form ekliyorum. Daha önce oluşturduğumuz template dosyasında class adını vermemiştik ($myproperty$). Class'ın adını ekleyeceğimiz formdan alacağız.

public partial class WizardFrm : Form
    {
        public WizardFrm()
        {
            InitializeComponent();
        }

        public string MyProperty { get; set; } //framework 3.5

        private void goBtn_Click(object sender, EventArgs e)
        {
            MyProperty = txtMyProp.Text;
            this.Dispose();
        }
    }

Daha sonra IWizard interface'ini implement eden bir class oluşturuyoruz. Bu interface'in 6 metodunun içini istediğimiz gibi dolduruyoruz.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TemplateWizard;
using EnvDTE;
using System.Windows.Forms;

namespace TemplateWizard
{
    public class CustomeWizard : IWizard
    {
        // This method is called before opening any item that
        // has the OpenInEditor attribute.
        public void BeforeOpeningFile(ProjectItem projectItem)
        {
        }

        public void ProjectFinishedGenerating(Project project)
        {
        }

        // This method is only called for item templates,
        // not for project templates.
        public void ProjectItemFinishedGenerating(ProjectItem
            projectItem)
        {
        }

        // This method is called after the project is created.
        public void RunFinished()
        {
        }

        public void RunStarted(object automationObject,
            Dictionary<string, string> replacementsDictionary,
            WizardRunKind runKind, object[] customParams)
        {
            try
            {
                // Display a form to the user. The form collects
                // input for the custom message.
                WizardFrm wizardFrm = new WizardFrm();
                wizardFrm.ShowDialog();

                // Add custom parameters.
                replacementsDictionary.Add("$myproperty$",
                    wizardFrm.MyProperty);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        // This method is only called for item templates,
        // not for project templates.
        public bool ShouldAddProjectItem(string filePath)
        {
        }
    }
}


Ben RunStarted metodunu kullandım, çünkü çalışmaya başladığı anda formun açılmasını istiyorum. Metot içinde form açılıyor ve $myproperty$ sözlüğe eklenerek, class adı yerine, MyProperty'ye atanan, textbox'dan alınan değer yazılmış olunuyor.
Şimdi anlatacağım kısmı neden yaptığımızı çok fazla anlayamasam da  gerekli olduğunu biliyorum :) Sanırım oluşan dll'i kullanabilmek için gerekli. Project sekmesi altında Properties'e giriyoruz. Signing sekmesinde Sign the assembly checkbox'ı işaretlenir ve Choose a strong name key file ile New diyerek bir isim giriyoruz. Şifre isteğe bağlı. Sonra oluşturduğumuz bu projenin dll'ini, vs2008 command prompt'da gacutil /i <assembly_path> komutu ile veya C:\WINDOWS\assembly altına sürükle bırak ile yüklüyoruz.
Şimdi bu assemly'yi kullanarak, Belgelerim/Visual Studio 2008/Templates/ProjectTemplates altındaki template zip dosyamızı unzipliyoruz. vstemplate uzantılı dosyayı notepad'de açarak TemplateContent tag'ından sonra WizardExtension tag'ını ekliyoruz.


<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
<TemplateData>
<DefaultName>templatePrj.cs</DefaultName>
<Name>templatePrj</Name>
<Description><No description available></Description>
<ProjectType>CSharp</ProjectType>
<SortOrder>10</SortOrder>
<Icon>__TemplateIcon.ico</Icon>
</TemplateData>
<TemplateContent>
<References />
<ProjectItem SubType="Code" TargetFileName="$fileinputname$.cs" ReplaceParameters="true">Class1.cs</ProjectItem>
</TemplateContent>
<WizardExtension>
<Assembly>TemplateWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=22fc27524b3fae32</Assembly>
<FullClassName>TemplateWizard.CustomeWizard</FullClassName>
</WizardExtension>
</VSTemplate>


C:\WINDOWS\assembly altına yüklediğimiz dll'e sağ tıklayarak özelliklerinden public key token'a ve versiyonuna bakarak WizardExtension kısmını yazabiliriz.
Son olarak değiştirdiğimiz vstemplate dosyası ile template zip dosyasını güncelliyoruz. Bu zip dosyasını ben Visual C# altında görünmesini istediğim için Belgelerim\Visual Studio 2008\Templates\ProjectTemplates\Visual C# altına koydum. Unutmayın ki sadece zip dosyalarını algılıyor!




Buradan girilen isim class adı olarak yazılıyor.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class MyNewClass
{
}

İşlem bu kadar! Çok zor görünse de template altında görüp de çalıştırabilince çok zevkli oluyor :)




Hiç yorum yok:

Yorum Gönder