Por ejemplo, dado un directorio base que contiene carpetas de aplicaciones Squirrel como "app-1.0.0", "app-1.2.3" y "app-2.0.0", estas funciones devolverán la lista de esos directorios ordenados por versión, de forma ascendente, de manera que puedas acceder fácilmente al directorio más antiguo (app-1.0.0) o al más reciente (app-2.0.0), o eliminar los más antiguos, etc.
Otro ejemplo, sería con el directorio de Google Chrome. Por ejemplo, si tuvieramos un directorio base "C:\Program Files\Google Chrome\App\Chrome-bin" con las carpetas de instalación de Google Chrome como "100.0.4896.127", "101.0.4951.64" y "102.0.5005.63", estas funciones devolverían los directorios ordenados por versión.
Código
''' <summary> ''' Returns a collection of application versioned directories ''' found within the specified base directory, sorted by version. ''' </summary> ''' ''' <example> This is a code example. ''' <code language="VB"> ''' Dim baseDir As String = "C:\Program Files\Squirrel Application" ''' Dim namePrefix As String = "app-" ' Case: "app-1.0.0" ''' Dim nameSuffix As String = Nothing ''' ''' Dim versionedDirs As SortedList(Of Version, DirectoryInfo) = ''' GetVersionedDirectories(baseDir, namePrefix, nameSuffix) ''' ''' Dim oldest As DirectoryInfo = versionedDirs.First.Value ''' Dim newest As DirectoryInfo = versionedDirs.Last.Value ''' ''' Console.WriteLine($"Oldest versioned directory name: {oldest.Name}") ''' Console.WriteLine($"Newest versioned directory name: {newest.Name}") ''' </code> ''' </example> ''' ''' <param name="baseDir"> ''' The base directory that contains application versioned directories (for example: "<b>app-1.0.0</b>"). ''' </param> ''' ''' <param name="namePrefix"> ''' Optional. If specified, only directory names that begin with this prefix are included. ''' <para></para> ''' Default value is null. ''' </param> ''' ''' <param name="nameSuffix"> ''' Optional. If specified, only directory names that ends with this suffix are included. ''' <para></para> ''' Default value is null. ''' </param> ''' ''' <returns> ''' A <see cref="SortedList(Of Version, DirectoryInfo)"/> where the keys are ''' <see cref="Version"/> objects parsed from the directory names, and the values ''' are the corresponding <see cref="DirectoryInfo"/> objects. ''' <para></para> ''' The collection is sorted in ascending order by version, ''' so <see cref="Enumerable.First"/> returns the oldest application version directory, ''' and <see cref="Enumerable.Last"/> returns the newest. ''' </returns> ''' ''' <exception cref="ArgumentNullException"> ''' Thrown when the specified <paramref name="baseDir"/> is null. ''' </exception> ''' ''' <exception cref="DirectoryNotFoundException"> ''' Thrown when the specified <paramref name="baseDir"/> does not exist. ''' </exception> <DebuggerStepThrough> Public Shared Function GetVersionedDirectories(baseDir As String, Optional namePrefix As String = Nothing, Optional nameSuffix As String = Nothing ) As SortedList(Of Version, DirectoryInfo) Dim prefixText As String = If(String.IsNullOrEmpty(namePrefix), "", Regex.Escape(namePrefix)) Dim suffixText As String = If(String.IsNullOrEmpty(nameSuffix), "", Regex.Escape(nameSuffix)) Dim versionGroup As String = "(?<version>\d+(\.\d+){0,3})" Dim pattern As String = $"^{prefixText}{versionGroup}{suffixText}$" Dim searchRegex As New Regex(pattern, RegexOptions.IgnoreCase Or RegexOptions.Compiled) Return GetVersionedDirectories(baseDir, searchRegex) End Function ''' <summary> ''' Returns a collection of application versioned directories ''' found within the specified base directory, sorted by version. ''' </summary> ''' ''' <example> This is a code example. ''' <code language="VB"> ''' Dim baseDir As String = "C:\Program Files\Squirrel Application" ''' Dim pattern As String = "^app-(?<version>\d+(\.\d+){0,3})$" ' Case: "app-1.0.0" ''' Dim searchRegex As New Regex(pattern, RegexOptions.IgnoreCase Or RegexOptions.Compiled) ''' ''' Dim versionedDirs As SortedList(Of Version, DirectoryInfo) = ''' GetVersionedDirectories(baseDir, searchRegex) ''' ''' Dim oldest As DirectoryInfo = versionedDirs.First.Value ''' Dim newest As DirectoryInfo = versionedDirs.Last.Value ''' ''' Console.WriteLine($"Oldest versioned directory name: {oldest.Name}") ''' Console.WriteLine($"Newest versioned directory name: {newest.Name}") ''' </code> ''' </example> ''' ''' <param name="baseDir"> ''' The base directory that contains application versioned directories (for example: "<b>app-1.0.0</b>"). ''' </param> ''' ''' <param name="searchRegex"> ''' A <see cref="Regex"/> used to filter the directory names. ''' <para></para> ''' ⚠️ This regex must contain a named group called <b>version</b>, ''' which will be used to extract the version number from the directory name. ''' <para></para> ''' For example: <c>"^app-(?<version>\d+(\.\d+){0,3})$"</c> ''' </param> ''' ''' <returns> ''' A <see cref="SortedList(Of Version, DirectoryInfo)"/> where the keys are ''' <see cref="Version"/> objects parsed from the directory names, and the values ''' are the corresponding <see cref="DirectoryInfo"/> objects. ''' <para></para> ''' The collection is sorted in ascending order by version, ''' so <see cref="Enumerable.First"/> returns the oldest application version directory, ''' and <see cref="Enumerable.Last"/> returns the newest. ''' </returns> ''' ''' <exception cref="ArgumentNullException"> ''' Thrown when the specified <paramref name="baseDir"/> or <paramref name="searchRegex"/> is null. ''' </exception> ''' ''' <exception cref="ArgumentException"> ''' Thrown when the pattern of the specified <paramref name="searchRegex"/> does not contain a named group 'version'. ''' </exception> ''' ''' <exception cref="DirectoryNotFoundException"> ''' Thrown when the specified <paramref name="baseDir"/> does not exist. ''' </exception> <DebuggerStepThrough> Public Shared Function GetVersionedDirectories(baseDir As String, searchRegex As Regex ) As SortedList(Of Version, DirectoryInfo) If String.IsNullOrWhiteSpace(baseDir) Then Throw New ArgumentNullException(NameOf(baseDir)) End If If searchRegex Is Nothing Then Throw New ArgumentNullException(NameOf(searchRegex)) End If If Not searchRegex.GetGroupNames().Contains("version") Then Throw New ArgumentException("The provided regex pattern must contain a named group 'version'.", NameOf(searchRegex)) End If If Not Directory.Exists(baseDir) Then Throw New DirectoryNotFoundException(baseDir) End If Dim topLevelDirs As DirectoryInfo() = New DirectoryInfo(baseDir). GetDirectories("*", SearchOption.TopDirectoryOnly) Dim versionedDirs As New SortedList(Of Version, DirectoryInfo)( topLevelDirs.Length, Comparer(Of Version).Default ) For Each topLevelDir As DirectoryInfo In topLevelDirs Dim match As Match = searchRegex.Match(topLevelDir.Name) If match.Success Then Dim versionPart As String = match.Groups("version").Value Dim ver As Version = Nothing If Version.TryParse(versionPart, ver) Then If Not versionedDirs.ContainsKey(ver) Then versionedDirs.Add(ver, topLevelDir) End If End If End If Next Return versionedDirs End Function
Tiene dos formas de empleo. La primera es mediante un prefijo y/o sufijo, siendo ambos opcionales:
Código
Dim baseDir As String = "C:\Program Files\Squirrel Application" Dim namePrefix As String = "app-" ' Case: "app-1.0.0" Dim nameSuffix As String = Nothing Dim versionedDirs As SortedList(Of Version, DirectoryInfo) = GetVersionedDirectories(baseDir, namePrefix, nameSuffix) Dim oldest As DirectoryInfo = versionedDirs.First.Value Dim newest As DirectoryInfo = versionedDirs.Last.Value Console.WriteLine($"Oldest versioned directory name: {oldest.Name}") Console.WriteLine($"Newest versioned directory name: {newest.Name}")
La segunda forma de utilizarlo es mediante una expresión regular que debe incluir un grupo nombrado como "version":
Código
Dim baseDir As String = "C:\Program Files\Squirrel Application" Dim pattern As String = "^app-(?<version>\d+(\.\d+){0,3})$" ' Case: "app-1.0.0" Dim searchRegex As New Regex(pattern, RegexOptions.IgnoreCase Or RegexOptions.Compiled) Dim versionedDirs As SortedList(Of Version, DirectoryInfo) = GetVersionedDirectories(baseDir, searchRegex) Dim oldest As DirectoryInfo = versionedDirs.First.Value Dim newest As DirectoryInfo = versionedDirs.Last.Value Console.WriteLine($"Oldest versioned directory name: {oldest.Name}") Console.WriteLine($"Newest versioned directory name: {newest.Name}")





