Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc

CustomTool dla Visual Studio


Ostatnio, w kontekście zine #2, dużo pisaliśmy o tym jak generować kod. Mnie ostatnio zainteresowała kwestia integracji generatora z Visual Studio. Wiedziałem, że jest to możliwe patrząc chociażby na generator zasobów, czy typowanych datasetów. Wiedziałem, że VS dla danego pliku w solucji udostępnia właściwość CustomTool, w której możemy podać nazwę generatora, który na podstawie tego pliku wygeneruje nowy plik i podłączy go jako potomka do pliku źródłowego w drzewie projektów. Trzeba było się tylko dowiedzieć jak taki custom tool napisać. Okazało się, że nie jest to takie skomplikowane i da się napisać w postaci kodu zarządzanego.

Visual Studio do komunikacji z custom toolem wykorzystuje COMa. Jak się dowiedziałem kod opakowujący odpowiednie interfejsy był w SDK do Visual Studio 2002 dostępny w pliku Microsoft.VSDesigner.dll natomiast w późniejszych wydaniach został schowany. Można go natomiast ściągnąć ze strony [1]. Ponadto wymagane jest Visual Studio SDK, które dostarcza kilku wymaganych bibliotek. Mając te wszystkie elementy zadanie implementacji jest banalnie proste.

Custom tool to klasa, która dziedziczy po klasie BaseCodeGeneratorWithSite. Dodatkowo klasa ta musi być oznaczona dwoma atrybutami: Guid oraz ComVisible. Poniżej znajduje się przykładowa implementacjia:

[Guid("408ABA1A-9AD7-41a9-8ECE-4B35C4D5208D")]
[ComVisible(true)]
public class Testowy : BaseCodeGeneratorWithSite
{
    public override string GetDefaultExtension()
    {
        return ".xml";
    }
    protected override byte[] GenerateCode(string inputFileName, string inputFileContent)
    {
        string generatedCode = "Wygenerowałeś mnie :)";
        return Encoding.ASCII.GetBytes(generatedCode);
    }
}

Najważniejsza metoda to GenerateCode. Jest to metoda, którą wywołuje Visual Studio generując plik. Zwracana jest tablica bajtów, która zapisywana jest do generowanego pliku. Nazwa generowanego pliku jest zawsze taka sama jak nazwa pliku źródłowego. Możemy wpłynąć na rozszerzenie nadpisując metodę GetDefaultExtension. To wszystko co trzeba zrobić, aby zaimplementować custom toola.

Drugim krokiem jest jego rejestracja. Visual Studio wczytuje informacje o dostępnych custom toolach z rejestru i tam musimy umieścić swój wpis. Oto zawartość pliku, który tworzy odpowiedni wpis w rejestrze:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Generators\<identyfikator projektu>\<nazwa custom toola>]

@="<nazwa custom toola>"

"CLSID"="<id toola>”

"GeneratesDesignTimeSource"=dword:00000001

Należy w tym miejscu wytłumaczyć kilka elementów:

<identyfikator projektu> to guid wskazujący na typ projektu. {fae04ec1-301f-11d3-bf4b-00c04f79efbc} to guid odnoszący się do projektów w języku C#. Gdybyśmy chcieli dodać generator dla VB.Net to musielibyśmy umieścić nasz wpis w gałęzi {164b10b9-b200-11d0-8c61-00a0c91e29d5}

<nazwa custom toola> to nazwa którą będziemy wpisywali w VS w pole CustomTool.

<id toola> to guid, którym opatrzona jest klasa, którą zaimplementowaliśmy, czyli {408ABA1A-9AD7-41a9-8ECE-4B35C4D5208D}

Ostatni parametr wskazuje na to, czy VS ma wygenerować plik i dołączyć go do projektu.


Ostatnim krokiem, który musimy wykonać jest zarejestrowanie naszej klasy w systemie, aby można go było używać jako obiektu COM. Wykorzystujemy do tego narzędzie tlbexp.exe do wyekstrahowania interfejsu z naszego assembly oraz regasm.exe do rejestracji w systemie. Docelowo assembly z custom toolem powinno posiadać silną nazwę, ale na potrzeby eksperymentalne możemy ten krok pominąć.

tlbexp Testowy.dll

regasm /codebase Testowy.dll

Teraz możemy już ponownie uruchomić Visual Studio i wypróbować generator.

Przedstawione tutaj rozwiązanie pozwala generować tylko jeden plik. Czasami chcielibyśmy mieć możliwość wygenerowania kilku plików. Nie jest to niemożliwe :) Implementację klas bazowych umożliwiających generowanie wielu plików znalazłem na CodeProject [2].

 

[1] http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=4AA14341-24D5-45AB-AB18-B72351D0371C

[2] http://www.codeproject.com/useritems/VsMultipleFileGenerator.asp

 


Opublikowane 5 kwietnia 2007 18:10 przez nuwanda

Powiadamianie o komentarzach

Jeżeli chciałbyś otrzymywać email gdy ta wypowiedź zostanie zaktualizowana, to zarejestruj się tutaj

Subskrybuj komentarze za pomocą RSS

Komentarze:

Brak komentarzy

Co o tym myślisz?

(wymagane) 
wymagane 
(wymagane) 

  
Wprowadź kod: (wymagane)