| 

.NET C# Java Javascript Exception

6
Guten Morgen,

ich bastel mir gerade eine umfangreiche Projektvorlage und habe ein kleines Problem mit den SolutionFolders. Wenn man in VS eine leere Projektmappe anlegt, kann man diese ja mit "logischen Ordnern" strukturieren. Mit "logisch" meine ich, das sie nicht physikalisch auf der Festplatte als Ordner angelegt werden.

Nun versuche ich dasselbe mit einer Projektvorlage. Dafür gibt es einen Abschnitt "SolutionFolder"

<TemplateContent>
<ProjectCollection>
<SolutionFolder Name="2. Application">
<ProjectTemplateLink ProjectName="$shortname$.Application.Interfaces">.Application.Interfaces\Application.Interfaces.vstemplate</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$shortname$.Application.Services">Application.Services\Application.Services.vstemplate</ProjectTemplateLink>
</SolutionFolder>
<SolutionFolder Name="3. Domain">
<ProjectTemplateLink ProjectName="$shortname$.Domain.Model">Domain.Model\Domain.Model.vstemplate</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$shortname$.Domain.Repository">Domain.IRepository\Domain.IRepository.vstemplate</ProjectTemplateLink>
</SolutionFolder>
<SolutionFolder Name="4. Infrastructure">
<ProjectTemplateLink ProjectName="$shortname$.Infrastructure.EF">Infrastructure.EF\Infrastructure.EF.vstemplate</ProjectTemplateLink>
</SolutionFolder>
<SolutionFolder Name="1. UI">
<ProjectTemplateLink ProjectName="$shortname$.UI">UI\UI.vstemplate</ProjectTemplateLink>
</SolutionFolder>
</ProjectCollection>
<CustomParameters />
</TemplateContent>


Dummerweise werden aber hier die Ordner "1. UI", "2. Application" etc. auch als physikalischer Ordner mit angelegt. Das wäre zwar ertragbar, aber doch nicht gewünscht, von meiner Seite her.

Hat hier jemand Ideen, wie man das vermeiden kann? Die MSDN ist nach wie vor grottig, da steht ja nur drin "Mit dem SolutionFolder können Sie einen SolutionFolder einfügen".

Ich habe schon in den <TemplateData> den Eintrag <CreateNewFolder>false</CreateNewFolder> versucht, und auch alle "CreateNewfolder" in den Unterprojekten auf False gesetzt, nur hatte dies rein gar keine Wirkung. Die Projekte sehen absolut identisch aus.

Google war mir auch keine Hilfe, so dass ich hoffe, das sich hier jemand findet.

Dankeschön vorab,
Jens Duczmal
04.01.2012
Jens Duczmal 2,6k 1 3 9
Jens Duczmal 2,6k 1 3 9
1 Antwort
2
Microsoft ist mir ja ein Rätsel. Da ermöglichen die es, in VS Projektmappenordner anzulegen, die nur Virtuell sind. Dann ermöglichen sie es, dies auch in den Templates zu tun, aber legen die dort IMMER physikalisch an, anstatt hier einfach genau so zu arbeiten oder wenigstens ein "IsVirtual=True" mit einzubauen. Immer dasselbe. Kaum sieht man mal etwas interessantes, muss man feststellen das es mal wieder nur halbherzig implementiert ist. Dafür könnte ich MS echt in den Hintern treten......

Genug aufgeregt, ich hätte hier eine Lösung anzubieten.

Das Template kann quasi unverändert bleiben, und das eigentliche Anlegen geschieht nun per Code im Wizard. Die SolutionFolders sind danach dann nur Virtuell, wie beabsichtigt] (müsst Ihr selbst nach C# konvertieren, wir arbeiten leider mit VB)

1) Die ProjectCollection wird im Template verschoben. Sie wandert jetzt exakt wie sie ist, in die WizardData.
<WizardData>
<ProjectCollection>
<SolutionFolder Name="2. Application">
...


2) Die RunStarted-Methode wird wie folgt ergänzt
Private dte As EnvDTE._DTE
Private _runKind As WizardRunKind
Private _replacementsDictionary As Dictionary(Of String, String)

Public Sub RunStarted(automationObject As Object, replacementsDictionary As System.Collections.Generic.Dictionary(Of String, String), runKind As Microsoft.VisualStudio.TemplateWizard.WizardRunKind, customParams() As Object) Implements Microsoft.VisualStudio.TemplateWizard.IWizard.RunStarted
dte = DirectCast(automationObject, EnvDTE.DTE)
_runKind = runKind
_replacementsDictionary = replacementsDictionary

Dim sPath = CStr(customParams(0))
sPath = sPath.Substring(0, sPath.LastIndexOf("\") + 1)
_replacementsDictionary.Add("$templatepath$", sPath)
End Sub


3) Wirklich erstellt werden die SolutionFolders und die Unterprojekte nun in RunFinished:
Public Sub RunFinished() Implements Microsoft.VisualStudio.TemplateWizard.IWizard.RunFinished
If _runKind = WizardRunKind.AsMultiProject Then
Dim sol = DirectCast(dte.Solution, Solution2)
AddFolders(sol, _replacementsDictionary("$wizarddata$"))
End If
End Sub

Private Sub AddFolders(solution As Solution2, xmlstring As String)

Dim ns = "http://schemas.microsoft.com/developer/vstemplate/2005"
Dim xDoc = XDocument.Load(New StringReader(xmlstring))
Dim xRoot As XElement = xDoc.Root

Dim currentFolder As Project = Nothing
Dim xAtt As XAttribute

For Each element In xRoot.Descendants(XName.Get("SolutionFolder", ns))
xAtt = element.Attribute(XName.Get("Name"))
If Not xAtt Is Nothing Then

currentFolder = solution.AddSolutionFolder(xAtt.Value)

For Each template In element.Descendants(XName.Get("ProjectTemplateLink", ns))
Dim templatePath = template.Value
Dim projectName As String

xAtt = template.Attribute(XName.Get("ProjectName"))
If Not xAtt Is Nothing Then
projectName = xAtt.Value.Replace("$shortname$", _shortName)

Dim destinationPath = _replacementsDictionary("$destinationdirectory$") & "\" & projectName
Directory.CreateDirectory(destinationPath)

Dim SF As SolutionFolder
SF = CType(currentFolder.Object, SolutionFolder)
SF.AddFromTemplate(_replacementsDictionary("$templatepath$") & templatePath, destinationPath, projectName)

End If
Next
End If
Next
End Sub


Im Prinzip müsst Ihr nur Euren Wizard erweitern und sonst kann die ProjectCollection halt exakt wie sie ist, etwas verschoben werden. Dies halte ich für eine recht angenehme Lösung. Der Quellcode funktioniert, könnte vielleicht etwas eleganter sein, aber nach 6 Stunden Suche mag ich langsam nicht mehr.

Viel Spass damit
Jens

Hm...Nichtmal CK unterstützt wohl VB, wenn ich mir die Farbgebung mal anschaue :)
05.01.2012
Jens Duczmal 2,6k 1 3 9
+1 Gut zu wissen und danke für's Teilen, auch wenn ich es aktuell grad nicht brauche.
Was die Farbgebung angeht: das liegt vermutlich nicht an VB, sondern dürfte ein allgemeiner Bug in CK sein. Er kommt bei "\" durcheinander und erkennt das Schließen des Strings nicht. Ein "\\" hilft leider nicht, kurioserweise kann man mit "\\\" dann aber einen doppelten Backslash wieder korrekt darstellen.
Ein ähnliches Problem gibt es mit [i], das im Code als \[i] geschrieben werden muss, damit es korrekt dargestellt wird. Lästig, weil man dadurch nicht einfach C&P nutzen kann.
Matthias Hlawatsch 05.01.2012
+1
Trifft sich, dass das Thema gerade jetzt auftaucht, da ich in für die nahe Zukunft geplant hatte mir für meine Projekte auch mal ein Template zu machen. Diese virtuellen Ordner kommen mir da gerade Recht.
Karill Endusa 05.01.2012
Danke :) Schön, das es auch Andere interessiert.
Jens Duczmal 05.01.2012

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH