Hi!
Hier ein Winz-Konsole-Programm (eiglich nur eine Methode), welches ein Directory scant, und alle Projekt-Dateien (c# oder vb.net) in einer SolutionDatei zusammenschmeisst.
So eine "SuperSolution" ist manchmal nützlich, wenn man grossflächig Änderungen vornehmen will (etwa aus allen Projekten, die man hat, den
Das umzusetzen ist kein Hexenwerk, ein Solution-File
Also je Projekt brauche ich 1) die ProjectType-Guid, 2) AssemblyNamen, 3) relativen Pfad zur Projekt-Datei, 4) individuellen ProjectGuid.
ProjectType-Guids sind fest vorgegeben -
AssemblyNamen und rel. Pfad ergeben sich aussm Pfad der gefundenen Projekt-Datei, und die ProjectGuid liest man aus der Projekt-Datei aus - ist ja Xml.
Ich zeige einfach mal die
Wie man anne
Die Wirkung ist, man kann aussm Datei-Explorer einen Ordner auf die
Im Ordner werden die Dateien
Erstere Datei wird via
Letztere ist eine lauffähige Solution, mit allen gefundenen Project-Files.
Points of Interest
Die angehängte Solution enthält auch ein (wirklich!) kleines Helpers-Project, weil ohne zumindest ein paar meiner Extensions kann ich garnet proggen
Das bedeutet: Wenn man obiges Snippet nur auskopiert müsste es noch bisserl angepasst werden, dasses ohne meine Extensions auskommt.
Hier ein Winz-Konsole-Programm (eiglich nur eine Methode), welches ein Directory scant, und alle Projekt-Dateien (c# oder vb.net) in einer SolutionDatei zusammenschmeisst.
So eine "SuperSolution" ist manchmal nützlich, wenn man grossflächig Änderungen vornehmen will (etwa aus allen Projekten, die man hat, den
Microsoft.VisualBasic
- General-Import rauswerfen)Das umzusetzen ist kein Hexenwerk, ein Solution-File
*.sln
mit zB zwei Projekten sieht im simpelsten Falle so aus:Quellcode
- Microsoft Visual Studio Solution File, Format Version 12.00
- # Visual Studio 15
- Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "GatherProjects", "GatherProjects\GatherProjects.vbproj", "{DC1DBFB6-7A2A-4689-B01D-B90BCBE2228F}"
- EndProject
- Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Helpers", "Helpers\Helpers.vbproj", "{B95FCBC2-67AC-44D8-886F-0BECAB34F3A3}"
- EndProject
Also je Projekt brauche ich 1) die ProjectType-Guid, 2) AssemblyNamen, 3) relativen Pfad zur Projekt-Datei, 4) individuellen ProjectGuid.
ProjectType-Guids sind fest vorgegeben -
vb.net: {F184B08F-C81C-45F6-A57F-5ABD9991F28F}
, c#: {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
AssemblyNamen und rel. Pfad ergeben sich aussm Pfad der gefundenen Projekt-Datei, und die ProjectGuid liest man aus der Projekt-Datei aus - ist ja Xml.
Ich zeige einfach mal die
Class Program
VB.NET-Quellcode
- #Region "FileHeader"
- #If False Then
- Scanne das angegebene Directory nach .csproj und .vbproj und generiere daraus ein simples SolutionFile - sowas:
- Microsoft Visual Studio Solution File, Format Version 12.00
- # Visual Studio 2017
- Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Helpers", "Helpers\Helpers.vbproj", "{A7563141-631B-466C-B928-012FE954C193}"
- EndProject
- Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "GatherProjects", "GatherProjects\GatherProjects.vbproj", "{4BE11612-3597-45DA-B27F-3A457125E64C}"
- EndProject
- #End If '-- Options, Imports
- Imports System.IO
- Imports <xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- #End Region 'FileHeader
- Public Class Program
- Public Shared Sub Main(ParamArray commandlineArgs() As String)
- Dim diRoot = New DirectoryInfo(commandlineArgs(0)) ' Solution-Ordner: hier hinein wird die Ausgabe-Datei 'GatheredProjects.sln' gelegt
- Dim rootPathLen = diRoot.FullName.TrimEnd("\"c).Length + 1
- Dim projTypeGuids As New Dictionary(Of String, String) From {{".csproj", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"},
- {".vbproj", "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"}}
- Dim outputLines = {"Microsoft Visual Studio Solution File, Format Version 12.00", "# Visual Studio 2017"}.ToList
- For Each fiProj In diRoot.EnumerateFiles("*.??proj", SearchOption.AllDirectories)
- Try
- Dim projTypeGuid As String = Nothing
- If Not projTypeGuids.TryGetValue(fiProj.Extension.ToLower, projTypeGuid) Then Continue For
- Dim relPath = fiProj.FullName.Substring(rootPathLen) ' relativer Pfad vom Solution-Ordner zur ProjektDatei
- Dim xdoc = Xml.Linq.XDocument.Load(fiProj.FullName)
- Dim xProjGuid = xdoc.<Project>.<PropertyGroup>.<ProjectGuid>.FirstOrDefault
- If xProjGuid Is Nothing Then
- outputLines.AddRange({"Error in", fiProj.FullName, "No ProjectGuid found"})
- Continue For
- End If
- 'sowas muss bei rauskommen:
- 'Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "GatherProjects", "GatherProjects\GatherProjects.vbproj", "{F4EEB15F-A0CD-4D71-9BEF-70B32F022682}"
- 'EndProject
- Dim line = $"Project(""{projTypeGuid}"") = ""{fiProj.GetFilenameWithoutExtension}"", ""{relPath}"", ""{xProjGuid.Value}"""
- outputLines.AddRange({line, "EndProject"})
- Catch ex As Exception
- outputLines.AddRange({"Error in", fiProj.FullName, ex.ToString})
- Continue For
- End Try
- Next
- With New FileInfo(diRoot.Combine("GatheredProjects.txt"))
- .WriteAllText(Lf.Between(outputLines), True)
- Diagnostics.Process.Start(.FullName)
- .CopyTo(.GetFullnameWithoutExtension & ".sln", True)
- End With
- End Sub
- End Class
Wie man anne
Sub Main()
sieht, wird das erste Kommandozeilen-Argument verarbeitet (zeile #18).Die Wirkung ist, man kann aussm Datei-Explorer einen Ordner auf die
GatherProjects.exe
ziehen, und dieser Ordner wird gescannt.Im Ordner werden die Dateien
GatheredProjects.txt
und GatheredProjects.sln
angelegt (Zeilen #45 - 47).Erstere Datei wird via
Process.Start()
gleich geöffnet, dass man sehen kann, was generiert wurde (und ob Fehler drinne sind).Letztere ist eine lauffähige Solution, mit allen gefundenen Project-Files.
Points of Interest
- Mein berühmter
FileHeader
, wo das wesentliche einer CodeDatei erklärt wird - aber auch die Imports versteckt - sieht im VisualStudio besser aus und kann man zuklappen, wenn mans nicht sehen will. - die beiden möglichen ProjectTypeGuids initialisiere ich in ein Dictionary, sodass ich später einfach anhand der Extension den richtigen Guid entnehmen kann bzw das Projekt überspringen (#20, 21 und #26).
- Der FileSearch-Filter matcht sowohl
*.csproj
als auch*.vbproj
indem er die vmtl. eher unbekannte Wildcard?
verwendet (#23) - In die
outputLines
tu ich immer gleich mehrere Zeilen, sowohl bei Initialisierung als auch später dann mittels.AddRange()
(#22, 31, 38, 40) - Auslesen des Project-Guids mit Xml.Linq (#29) - beachte auch den Xml-Namespace-Import:
Die angehängte Solution enthält auch ein (wirklich!) kleines Helpers-Project, weil ohne zumindest ein paar meiner Extensions kann ich garnet proggen
Das bedeutet: Wenn man obiges Snippet nur auskopiert müsste es noch bisserl angepasst werden, dasses ohne meine Extensions auskommt.
Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()