November 2010 - Einträge

Visual Studio 2010 Projektarten

Mir ist gerade etwas interessantes aufgefallen.. Bevor ich es vergesse schreib ich es lieber schnell auf.

Ich habe in VS2010 ein ganz normales Projekt erzeugt (Windows-Anwendung). Ich habe eine Testklasse geschrieben mit ganz normalen UnitTest-Attributen wie [TestClass] und [TestMethod] und ich konnte machen was ich wollte, meine Testmethoden sind einfach nicht in meinem Testlisten-Editor erschienen.

Ich habe mir dann einmal von Visual Studio ein richtiges Test-Projekt erzeugen lassen und da war alles schick. Ich habe meine selbstgeschriebenen Testklassen in das Test-Projekt kopiert und sofort wurden meine Testmethoden im Testeditor aufgelistet.

Wenn ich bei meinem normalen Windows-Projekt rechte Maustaste und Neues Element hinzufügen anklicke, so erscheint mir folgende Auswahl:

image

Mache ich das gleiche bei meinem Testprojekt, erscheint folgende Auswahl:

image

Interessant. Hier bietet mir VS auf einmal viel cooles Testzeug an, dafür aber keine Fenster und Steuerelemente-Sachen mehr. So, jetzt ging die Sucherei los… Wo war der Unterschied…

Ich habe die beiden Projektdateien verglichen und folgende interessante Zeile in dem normalen Windows-Projekt gefunden:

<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

Im Testprojekt sieht die Zeile so aus:

<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

Danach habe ich mal aus Spaß den ersten GUID, der nämlich den Unterschied darstellt auch einfach mit in mein Windows-Projekt kopiert. Die Zeile sieht dann da nun so aus:

<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

So. Und das Resultat in Visual Studio sieht dann so aus:

image

Nun hab ich alles. Yeah. Windows-Elemente sowie Testelemente. Und meine Testmethoden aus dem Projekt wurden auch sofort im Testlisten-Editor erkannt. Juhu.

Nun könnte ich mir noch viele andere GUIDs heraussuchen und ein Projekt zu einem ultimativen Monsterprojekt machen wo alles drin is… muss aber auch nicht sein. :-) Denn wenn man wie ich nun sein Windows-Projekt zu einem Testprojekt macht und es dann ausführen will, so werden auch nur die Tests gestartet, und nicht mehr das eigentliche Progrämmchen. Deswegen macht es auch viel mehr Sinn, einfach ein separates Testprojekt zu erzeugen, in dem einfach nur alle Tests ausgeführt werden.

Eine Liste von Projekttypen hab ich dann doch noch hier gefunden:

Project Type Description

Project Type Guid

Windows (C#)

{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}

Windows (VB.NET)

{F184B08F-C81C-45F6-A57F-5ABD9991F28F}

Windows (Visual C++)

{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}

Web Application

{349C5851-65DF-11DA-9384-00065B846F21}

Web Site

{E24C65DC-7377-472B-9ABA-BC803B73C61A}

Distributed System

{F135691A-BF7E-435D-8960-F99683D2D49C}

Windows Communication Foundation (WCF)

{3D9AD99F-2412-4246-B90B-4EAA41C64699}

Windows Presentation Foundation (WPF)

{60DC8134-EBA5-43B8-BCC9-BB4BC16C2548}

Visual Database Tools

{C252FEB5-A946-4202-B1D4-9916A0590387}

Database

{A9ACE9BB-CECE-4E62-9AA4-C7E7C5BD2124}

Database (other project types)

{4F174C21-8C12-11D0-8340-0000F80270F8}

Test

{3AC096D0-A1C2-E12C-1390-A8335801FDAB}

Legacy (2003) Smart Device (C#)

{20D4826A-C6FA-45DB-90F4-C717570B9F32}

Legacy (2003) Smart Device (VB.NET)

{CB4CE8C6-1BDB-4DC7-A4D3-65A1999772F8}

Smart Device (C#)

{4D628B5B-2FBC-4AA6-8C16-197242AEB884}

Smart Device (VB.NET)

{68B1623D-7FB9-47D8-8664-7ECEA3297D4F}

Workflow (C#)

{14822709-B5A1-4724-98CA-57A101D1B079}

Workflow (VB.NET)

{D59BE175-2ED0-4C54-BE3D-CDAA9F3214C8}

Deployment Merge Module

{06A35CCD-C46D-44D5-987B-CF40FF872267}

Deployment Cab

{3EA9E505-35AC-4774-B492-AD1749C4943A}

Deployment Setup

{978C614F-708E-4E1A-B201-565925725DBA}

Deployment Smart Device Cab

{AB322303-2255-48EF-A496-5904EB18DA55}

Visual Studio Tools for Applications (VSTA)

{A860303F-1F3F-4691-B57E-529FC101A107}

Visual Studio Tools for Office (VSTO)

{BAA0C2D2-18E2-41B9-852F-F413020CAA33}

SharePoint Workflow

{F8810EC1-6754-47FC-A15F-DFABD2E3FA90}

XNA (Windows)

{6D335F3A-9D43-41b4-9D22-F6F17C4BE596}

XNA (XBox)

{2DF5C3F4-5A5F-47a9-8E94-23B4456F55E2}

XNA (Zune)

{D399B71A-8929-442a-A9AC-8BEC78BB2433}

SharePoint (VB.NET)

{EC05E597-79D4-47f3-ADA0-324C4F7C7484}

SharePoint (C#)

{593B0543-81F6-4436-BA1E-4747859CAAE2}

Silverlight

{A1591282-1198-4647-A2B1-27E5FF5F6F3B}

Tabelle 1: Projekttypen von Visual Studio 2010 (Quelle: http://www.mztools.com/Articles/2008/MZ2008017.aspx)

Eigene Templates mit Geburtsdatum für VS schreiben

Ich werde heute mal etwas nostalgisch in der Vergangenheit herumrühren und hier kurz beschreiben, wie man ein ItemTemplate für Visual Studio 2008 baut und individualisiert. Das heißt, wir legen mittels eines Templates zwei cs-Dateien an, eine resx-Datei und wir schreiben in irgendein Kommentar automatisiert das Geburtsdatum des Autors. Ja, ihr habt richtig gelesen. 2008. Asche über mein Haupt. Ich werd das aber demnächst für 2010 nachholen… :-) Aber da 2008 immer noch sehr häufig benutzt wird, dachte ich mir, ich mach das jetzt mal.

ItemTemplates oder auch ProjectTemplates sind die Vorlagen, die man in Visual Studio findet, wenn man ein Neues Projekt oder ein Neues Element hinzufügen möchte. Hier können auch eigene Templates geschrieben werden.

clip_image001

Wenn man ein neues Element hinzufügt so werden mindestens eine Datei, oder auch mehrere Dateien oder Ordner, dem Projekt hinzugefügt. In unserem Beispiel möchten wir eine Kommando-Klasse (z.B. SpeichernKommando) und ein Interface in einem separaten Use-Case-Ordner hinzufügen. Zusätzlich wollen wir noch eine Ressourcendatei anlegen. Danach wollen wir weitere Benutzereingaben entgegennehmen und ebenfalls in den Dateien hinterlegen. Hier kurz noch mal meine beiden cs-Dateien, die als Vorlage für ein Kommando dienen sollen.

SpeichernKommando.cs

   1: namespace WizardBeispiel
   2: {
   3:     public class SpeichernKommando : ISpeichernKommando
   4:     {
   5:         public SpeichernKommando()
   6:         {
   7:  
   8:         }
   9:  
  10:         public bool IsAvailable()
  11:         {
  12:             return true;
  13:         }
  14:  
  15:         public void Execute()
  16:         {
  17:             throw new NotImplementedException();
  18:         }
  19:     }
  20: }

 

ISpeichernKommando.cs

   1: namespace WizardBeispiel
   2: {
   3:     public interface ISpeichernKommando
   4:     {
   5:         bool IsAvailable();
   6:         void Execute();
   7:     }
   8: }

Zuerst erstellen wir uns eine Grundlage. Klick auf Datei –> Vorlage Exportieren

image

Dann befolgt ihr den Wizard. Wählt Symbolvorlage (für deutsche VS, englisch Item Template)

clip_image001[5]

Wählt die zu exportierende Datei aus. Obwohl hier Checkboxen sind und man ein additives Verhalten vermuten könnte, ist dem leider nicht so. Trotzdem können wir später mehr als nur eine Datei hinzufügen. Jetzt wählen wir einfach erstmal nur das Kommando.

clip_image001[7]

Wählt anschließend noch einige Assemblies, die ihr gern immer mit dabei haben möchtet, wenn ihr das Template auswählt. Auch hier könnt ihr später eigene Assemblies angeben.

clip_image001[9]

Im letzten Schritt könnt ihr ein Symbol wählen, eine Beschreibung anpassen und den Exportordner einsehen. Die Daten für das Template selbst können später alle noch verändert werden.

clip_image001[11]

Nachdem dieser Schritt ausgeführt wurde, entsteht eine zip-Datei in Eigene Dateien\Visual Studio 2008\My Exported Templates\. In meinem Beispiel beinhaltet diese 3 Dateien.

  • __TemplateIcon.ico
  • MyTemplate.vstemplate
  • SpeichernKommando.cs

Die Bilddatei zeigt das Bildchen an in Visual Studio, die cs-Datei ist die Datei, die später wirklich importiert werden soll und in der .vstemplate-Datei steht genau drin, was wohin importiert werden soll. Im Übrigen geht das hier natürlich mit VB genauso gut wie mit C#. Da es sich ja nun hier nicht mehr um das SpeichernKommando direkt handelt sondern um eine Vorlage für alle möglichen Kommandos, benennen wir die Datei einfach mal um in „Kommando.cs“. Der Name der Datei muss auch in der vsTemplate-Datei umbenannt werden. Die vsTemplate-Datei sieht nun wie folgt aus:

   1: <VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
   2:   <TemplateData>
   3:     <DefaultName>WizardBeispiel.cs</DefaultName>
   4:     <Name>WizardBeispiel</Name>
   5:     <Description>Beschreibung zu meinem Template</Description>
   6:     <ProjectType>CSharp</ProjectType>
   7:     <SortOrder>10</SortOrder>
   8:     <Icon>__TemplateIcon.ico</Icon>
   9:   </TemplateData>
  10:   <TemplateContent>
  11:     <References>
  12:       <Reference>
  13:         <Assembly>System</Assembly>
  14:       </Reference>
  15:     </References>
  16:     <ProjectItem SubType="Code" TargetFileName="$fileinputname$.cs" ReplaceParameters="true">Kommando.cs</ProjectItem>
  17:   </TemplateContent>
  18: </VSTemplate>

Wenn man sich hier unsere cs-Datei noch einmal anschaut, dann wird man feststellen, dass alle „personalisierten“ Informationen mit Platzhaltern versehen wurden. Der Namespace, der Name sowie der Konstruktor der Klasse beinhalten nun kryptische Platzhalter wie $rootnamespace$ oder $safeitemname$. Somit ist sichergestellt, dass später die Klasse im richtigen Namespace liegt, den richtigen Namen hat und auch alles wieder sofort kompilierbar ist. Der Parameter „" ReplaceParameters="true"” sorgt dafür, dass diese Platzhalter auch wirklich ersetzt werden.

Jetzt fehlen uns ja noch weitere Dateien. Wir kopieren unsere Interface-Datei auch noch in den Ordner, wo wir gerade unsere vsTemplate-Datei entpackt haben. Außerdem kopieren wir noch eine resx-Datei hinein. Wenn ihr keine habt, erzeugt in Visual Studio irgendwo schnell eine Neue und fügt diese ein. Die .Designer.cs-Datei brauchen wir hier nicht, die erzeugen wir nachher neu. Meine wird Resource.resx heißen.

Wir haben ja im Wizard gesagt, das Template soll gleich wieder nach Visual Studio importiert werden. „Importiert“ heißt kopiert, und zwar nach C:\Dokumente und Einstellungen\nfranze\Eigene Dateien\Visual Studio 2008\Templates\ItemTemplates. Befindet sich diese zip-Datei in diesem Ordner, so ist die Vorlage schon hinzugefügt, wenn man ein neues Element dem Projekt hinzufügen möchte.

clip_image001[13]

Auch das Icon findet sich wieder. Wenn wir nun dieses WizardBeispiel-Element einmal testweise hinzufügen zum Projekt, so erscheint unsere Datei, nur mit dem soeben neu eingegebenen Namen. Sollte die System-Assembly noch nicht als Verweis vorliegen, so würde sie mit hinzugefügt werden. So wie es in unserem Template angegeben ist.

Aber nun weiter in unserer vstemplate-Datei. Wir fügen nun zwei neue Zeilen ein und ändern eine vorhandene noch etwas ab, damit die Dateien in unserem UC-Ordner landen. Mit den beiden neuen Dateien möchten wir zusätzlich zum Kommando noch unsere Ressourcendatei sowie unser Interface hinzufügen. Unsere Datei sieht nun wie folgt aus.

   1: <TemplateContent>
   2:   <References>
   3:     <Reference>
   4:       <Assembly>System</Assembly>
   5:     </Reference>
   6:   </References>
   7:   <ProjectItem SubType="Code" TargetFileName="UC$fileinputname$\$fileinputname$.cs" OpenInEditor="true" ReplaceParameters="true">Kommando.cs</ProjectItem>
   8:   <ProjectItem SubType="Code" TargetFileName="UC$fileinputname$\I$fileinputname$.cs" ReplaceParameters="true">IKommando.cs</ProjectItem>
   9:   <ProjectItem SubType="Code" CustomTool="ResXFileCodeGenerator" TargetFileName="UC$fileinputname$\$fileinputname$Ressource.resx" ReplaceParameters="true">Resource.resx</ProjectItem>
  10: </TemplateContent>

Diese Zeilen besagen nun folgendes. Erstens werden alle drei Dateien in einem neuen Unterordner erstellt, der mit UC anfängt und weiterhin den Namen der Datei beinhaltet (ohne Endung). Wenn wir also ein Element hinzufügen und es „SpeichernKommando.cs“ nennen, so entsteht automatisch erstmal ein Ordner namens „UCSpeichernKommando“. Dieser Ordner enthält drei Dateien. Eine  SpeichernKommando.cs, eine ISpeichernKommando.cs sowie eine SpeichernKommandoRessource.resx.

Das OpenInEditor gibt an, welche Datei danach im Editor geöffnet werden soll. Ich finde das Kommando besser als z.B. das Interface oder die Ressourcendatei. Hier kann natürlich jeder machen was er will. Im Parameter Subtype steht drin, welcher Editor zum Öffnen benutzt werden soll.

Bei der Ressourcendatei ist es wichtig noch das CustomTool anzugeben. Dieses erzeugt automatisch die gewünschte .Designer.cs und ordnet sie der Ressourcendatei unter. Bei Ressourcendateien heißt das CustomTool, welches die Ressourcen.Designer.cs-Datei generiert „ResXFileCodeGenerator“. Solltet ihr andere Anwendungsfälle haben, so erzeugt euch einfach einmal eine entsprechende Datei ganz regulär in Visual studio und schaut euch die Dateieigenschaften an. Dort ist das CustomTool eingetragen, welches ihr hier in der Vorlage benutzen könnt.

clip_image001[15]

So, mein Ordner besteht nun aus folgenden Dateien.

  • __TemplateIcon.ico
  • MyTemplate.vstemplate
  • Kommando.cs
  • IKommando.cs
  • Ressource.resx

Bevor wir aber weitermachen müssen wir noch unser Interface anpassen. Aktuell sieht es so aus:

   1: namespace WizardBeispiel
   2: {
   3:     public interface ISpeichernKommando
   4:     {
   5:         bool IsAvailable();
   6:         void Execute();
   7:     }
   8: }

Hier ist noch nicht ein Platzhalter drin. Wir ändern es in folgendes ab

   1: namespace $rootnamespace$.UC$fileinputname$
   2: {
   3:     public interface $safeitemname$
   4:     {
   5:         bool IsAvailable();
   6:         void Execute();
   7:     }
   8: }

Nun befindet sich auch das Interface im richtigen Namespace (auch im Unterordner) und hat auch den richtigen Namen. Der gleiche Namespace sollte auch in dem Kommando selbst gewählt werden. Hier braucht man kein großes I vor den Platzhalter machen, das macht VS anscheinend automatisch.

In unserer Kommando.cs sollte das Interface aber auch benutzt werden. (Man beachte hier aber das I)

    public class $safeitemname$ : I$safeitemname$

Diese Dateien zippen wir nun und kopieren sie nach „C:\Dokumente und Einstellungen\nfranze\Eigene Dateien\Visual Studio 2008\Templates\ItemTemplates“. Schon können wir in Visual Studio „Neues Element“ hinzufügen und unsere Vorlage auswählen. Probieren wir das mal.

clip_image001[17]

Et voilà

clip_image001[19]

Und es kann sofort wieder kompiliert werden… Doll. Jetzt kommt der eigentliche Spaß. Ich möchte dass im Kommando automatisch das Geburtsdatum des Autors steht. Da Visual Studio das nicht erraten kann, muss es während des Hinzufügens irgendwo angegeben werden. Wir definieren in unserem Kommando die Stelle, wo wir das gern hinhaben möchten. Bei mir sieht das nun so aus, dass ich es über meiner Klasse eingefügt hab:

// $username$ hat Geburtstag am $geburtsdatum$

public class $safeitemname$ : I$safeitemname$

{

Den Platzhalter $username$ gibt es schon, den Platzhalter $geburtsdatum$ werden wir nachher selbst ersetzen. Im Übrigen gibt es folgende vordefinierte Platzhalter (Quelle: http://msdn.microsoft.com/en-us/magazine/cc188697.aspx):

Parameter

Beschreibung

itemname

The user-provided name from the dialog. This value is often used for naming classes and files.

safeitemname

The same as itemname but with all unsafe characters removed.

safeitemrootname

The name of the root item, which can be used for multi-item templates. For example, if you have partial classes, or a code-beside or code-behind scenario, you can use this item in the secondary files when you need the safeitemname of the main item being created.

projectname

The user-provided name of the project for a project template.

safeprojectname

The user-provided name of the project for a project template with all unsafe characters removed.

rootnamespace

The root namespace of the project for an item template, which can be used to replace the namespace in a project item source file.

guid[1-10]

A GUID that can be used as a unique identifier for uses such as project GUID in the project file. You can specify up to 10 different GUID parameters using the syntax: guidx, where x is a number between 1 and 10.

time

The current time in the format DD/MM/YYYY HH:MM:SS.

year

The current four-digit year.

username

The Windows username of the logged-in user.

userdomain

The Windows domain of the logged-in user.

machinename

The name of the machine where the template is being used.

clrversion

The version of the common language runtime being used.

registered-organization

The registered organization of the user based on the system settings.

wizarddata

A single string that can be any XML or string data included in the WizardData element in a template metadata file.

Zuerst erzeugen wir ein neues Visual Studio Projekt vom Typ Klassenbibliothek. Als Verweise fügen wir folgende ein:

  • EnvDTE.dll
  • Microsoft.VisualStudio.TemplateWizardInterface.dll

Die vorgefertigte Klasse Class1 nutzen wir gleich. Wir nennen sie „Wizard“ und implementieren das Interface „IWizard“ im namespace Microsoft.VisualStudio.TemplateWizard.

Damit diese Assembly benutzt werden kann, muss sie in den GAC. Damit sie da rein kann, muss sie signiert werden. Das geht in den Projekteigenschaften -> Tab „Signierung“. Dort Checkbox „Assembly signieren“ anhaken und in der Combobox bei Schlüsseldatei „Neu“ auswählen. In dem Fenster was erscheint, gebt ihr irgendeinen Namen für die Daten an z.B. „key“ und ein passwort braucht ihr hier nicht. Das sieht nun so aus

clip_image001[21]

Als nächstes fügen wir einen winzigen Dialog (Windows Form) hinzu. Ich nenne den Dialog „DataDialog“. Auf meinem Dialog platziere ich einfach nur einen DateTimePicker. So sieht das nun bei mir aus. Wehe hier schreibt irgendeiner ins Kommentar, dass der Dialog scheiße aussieht, oder er verzweifelt den „OK“-Button sucht… Das Ausschmücken des Dialoges überlasse ich der Phantasie des Lesers.

clip_image001[23]

Ich mache nun einfach auf die Schnelle eine Property in den Dialog, der den Wert des Datetimepickers zurückgibt. Später muss der Dialog einfach nur mittels „x“ oben rechts geschlossen werden.

   1: public DateTime Datum
   2: {
   3:     get { return dateTimePicker1.Value; }
   4:     set { dateTimePicker1.Value = value; }
   5: }

In dem Wizard entferne ich überall die throw NotImplementedExceptions und in der Methode RunStarted werden wir den Dialog anzeigen und selbst einen dieser Platzhalter ersetzen. Die Parameter der Methode „RunStarted“ sind automationObject, welches das DTE-Objekt ist, falls jemand hier noch mit dem CodeDOM oder anderen Visual Studio Features weiterarbeiten möchte. Weiterhin gibt es ein Dictionary. Dieses beinhaltet alle Platzhalter und ihre Ersetzungen. Hier brauchen wir unser Geburtsdatum nur noch hinzufügen. Mein code sieht wie folgt aus:

   1: public void BeforeOpeningFile(EnvDTE.ProjectItem projectItem)
   2: {
   3: }
   4:  
   5: public void ProjectFinishedGenerating(EnvDTE.Project project)
   6: {
   7: }
   8:  
   9: public void ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem)
  10: {
  11: }
  12:  
  13: public void RunFinished()
  14: {
  15: }
  16:  
  17: public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
  18: {
  19:     DataDialog dialog = new DataDialog();
  20:     dialog.ShowDialog();
  21:  
  22:     replacementsDictionary.Add("$geburtsdatum$", dialog.Datum.ToShortDateString());
  23: }
  24:  
  25: public bool ShouldAddProjectItem(string filePath)
  26: {
  27:     return true;
  28: }

Ok, so, nun ham wa ja schon viel geschafft. Wir kompilieren alles und werden nun unsere Assembly in den GAC einfügen. Das geht wie folgt. Im Startmenu „Microsoft Visual Studio 2008“->“Visual Studio Tools“->“Visual Studio 2008-Eingabeaufforderung“. Wichtig ist, IM ADMINISTRATORMODUS STARTEN (rechte Maustaste als Admin ausführen). Folgende Zeile eingeben:

Gacutil /i „C:\Dokumente und Einstellungen\nfranze\Eigene Dateien\Visual Studio 2008\Projects\ItemWizard\ItemWizard\ItemWizard\bin\Debug\ItemWizard.dll“

Wobei ihr natürlich hoffentlich euren Pfad nehmt… ;-)

Als letzte kleine Änderung müssen wir unseren Wizard nun auch noch bekannt machen in unserem Template. Dafür bearbeiten wir die vstemplate-Datei wie folgt.

   1: <VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
   2:   <TemplateData>
   3:       ...
   4:   </TemplateData>
   5:   <TemplateContent>
   6:       ...
   7:   </TemplateContent>
   8:   <WizardExtension>
   9:      <Assembly>ItemWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=859062e4da6d855b</Assembly>
  10:      <FullClassName>ItemWizard.Wizard</FullClassName>
  11:   </WizardExtension>
  12: </VSTemplate>

So, nun haben wirs. Nehmt euch wieder euren Ordner mit den ganzen Dateien drin, macht wieder eine zip draus und kopiert die Datei ins ItemTemplate-Verzeichnis. Und dann probiert mal, ob das so klappt.

Solltet ihr euch manchmal wundern, dass eure Änderungen im Wizard nicht übernommen werden, wenn ihr neu kompiliert und die Datei neu dem GAC zufügt, so startet mal Visual Studio neu.

Weiterhin habe ich einige Dokumentationen gesehen, in denen bei <WizardExtension><Assembly> immer nur der Assemblyname angegeben wurde, ohne Version und PublicKeyToken. Dies kann manchmal folgenden Fehler verursachen:

„Fehler: Diese Vorlage hat versucht, die nicht vertrauenswürdige Komponente „ItemWizard“ hinzuzufügen. Weitere Informationen zu diesem Problem und zum Aktivieren dieser Vorlage finden Sie in der Dokumentation über das Anpassen von Projektvorlagen.“

clip_image001[25]

So, und nun, liebe Entwicklungsleiter. Schreibt Vorlagen für eure Mitarbeiter und lasset sie sie benutzen. Jeder hat die gleichen Startvoraussetzungen, alle arbeiten mit gleichen Schemen, dies könnte ein großer Qualitätssprung in eurem Quellcode sein.

Nico Franze Herzlich Willkommen auf meinem Blog. Ich bin Nico, freier Softwareentwickler sowie Autor für Fachzeitschriften. Hab mit .NET Version 1.0 begonnen (damals noch VB.Net) und bin dann schlussendlich bei C# gelandet. Mehr Infos gibts unter www.nfranze.de


Suche

Los

Translator Widget

Dieser Blog

Syndikation


Locations of visitors to this page