Código
' *********************************************************************** ' Author : Elektro ' Modified : 16-March-2015 ' *********************************************************************** ' <copyright file="ResXManager.vb" company="Elektro Studios"> ' Copyright (c) Elektro Studios. All rights reserved. ' </copyright> ' *********************************************************************** #Region " Option Statements " Option Strict On Option Explicit On Option Infer Off #End Region #Region " Usage Examples " 'Imports System.IO 'Imports System.Text 'Public Class Form1 ' Private Sub Test() Handles MyBase.Shown ' Dim resX As New ResXManager(Path.Combine(Application.StartupPath, "MyResources.resx")) ' With resX ' ' Create or replace the ResX file. ' .Create(replace:=True) ' ' Add a string resource. ' .AddResource(Of String)("String Resource", "Hello World!", "String Comment") ' ' Add a bitmap resource. ' .AddResource(Of Bitmap)("Bitmap Resource", SystemIcons.Information.ToBitmap, "Bitmap Comment") ' ' Add a binary resource. ' .AddResource(Of Byte())("Binary Resource", File.ReadAllBytes("C:\file.mp3"), "Binary Comment") ' End With ' ' ******************************************************************************************************* ' ' Get the string resource. ' Dim stringResource As ResXManager.Resource(Of String) = ' resX.FindResource(Of String)("String Resource", StringComparison.OrdinalIgnoreCase) ' ' Get the bitmap resource. ' Dim bitmapResource As ResXManager.Resource(Of Bitmap) = ' resX.FindResource(Of Bitmap)("Bitmap Resource", StringComparison.OrdinalIgnoreCase) ' ' Get the binary resource. ' Dim binaryResource As ResXManager.Resource(Of Byte()) = ' resX.FindResource(Of Byte())("Binary Resource", StringComparison.OrdinalIgnoreCase) ' ' ******************************************************************************************************* ' ' Get the string data. ' Dim stringData As String = stringResource.Data ' ' Get the bitmap data. ' Dim bitmapData As Bitmap = bitmapResource.Data ' ' Get the binary data. ' Dim binaryData As Byte() = binaryResource.Data ' ' ******************************************************************************************************* ' ' Get all the resources at once. ' Dim resources As IEnumerable(Of ResXManager.Resource) = resX.Resources ' ' Get all the resources of specific Type at once. ' Dim stringResources As IEnumerable(Of ResXManager.Resource(Of String)) = resX.FindResources(Of String)() ' ' ******************************************************************************************************* ' ' Get all the resource datas at once from Resource collection. ' Dim resourceDatas As IEnumerable(Of Object) = ' From res As ResXManager.Resource In resX.Resources ' Select res.Data ' ' Get all the resource datas of specific Type at once from Resource collection. ' Dim stringResourceDatas As IEnumerable(Of String) = ' From res As ResXManager.Resource In resX.Resources ' Where res.Type Is GetType(String) ' Select DirectCast(res.Data, String) ' ' ******************************************************************************************************* ' ' Treat the string data as you like. ' MessageBox.Show(stringData, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Information) ' ' Treat the bitmap data as you like. ' Me.Icon = Icon.FromHandle(bitmapData.GetHicon) ' ' Treat the binary data as you like. ' File.WriteAllBytes("C:\new file.mp3", binaryData) ' ' ******************************************************************************************************* ' ' Iterate all the resources. ' For Each res As ResXManager.Resource In resX.Resources ' Dim sb As New StringBuilder ' sb.AppendLine(String.Format("Name...: {0}", res.Name)) ' sb.AppendLine(String.Format("Comment: {0}", res.Comment)) ' sb.AppendLine(String.Format("Type...: {0}", res.Type.ToString)) ' sb.AppendLine(String.Format("Data...: {0}", res.Data.ToString)) ' MsgBox(sb.ToString) ' Next ' ' Iterate all the resources of specific Type. ' For Each res As ResXManager.Resource(Of String) In resX.FindResources(Of String)() ' Dim sb As New StringBuilder ' sb.AppendLine(String.Format("Name...: {0}", res.Name)) ' sb.AppendLine(String.Format("Comment: {0}", res.Comment)) ' sb.AppendLine(String.Format("Type...: {0}", res.Type.ToString)) ' sb.AppendLine(String.Format("Data...: {0}", res.Data.ToString)) ' MsgBox(sb.ToString) ' Next ' ' ******************************************************************************************************* ' ' Remove a resource. ' resX.RemoveResource("Binary Resource") ' ' GC.Collect() ' End Sub 'End Class #End Region #Region " Imports " Imports System.ComponentModel Imports System.ComponentModel.Design Imports System.IO Imports System.Resources #End Region ''' <summary> ''' Manages a .Net managed resource file. ''' </summary> Public NotInheritable Class ResXManager #Region " Properties " ''' <summary> ''' Gets the .Net managed resource file path. ''' </summary> ''' <value>The .Net managed resource filepath.</value> Public ReadOnly Property FilePath As String Get Return Me.filePath1 End Get End Property ''' <summary> ''' The .Net managed resource file path. ''' </summary> Private ReadOnly filePath1 As String ''' <summary> ''' Gets the resources contained in the .Net managed resource file. ''' </summary> ''' <value>The resources.</value> Public ReadOnly Property Resources As IEnumerable(Of Resource) Get Return GetResources() End Get End Property #End Region #Region " Types " #Region " Resource " ''' <summary> ''' Defines a resource of a .Net managed resource file. ''' </summary> <Serializable> Public NotInheritable Class Resource #Region " Properties " ''' <summary> ''' Gets the resource name. ''' </summary> ''' <value>The resource name.</value> Public ReadOnly Property Name As String Get Return Me.name1 End Get End Property Private ReadOnly name1 As String ''' <summary> ''' Gets the resource data. ''' </summary> ''' <value>The resource data.</value> Public ReadOnly Property Data As Object Get Return Me.data1 End Get End Property Private ReadOnly data1 As Object ''' <summary> ''' Gets the resource type. ''' </summary> ''' <value>The resource type.</value> Public ReadOnly Property Type As Type Get Return Data.GetType End Get End Property ''' <summary> ''' Gets the resource comment. ''' </summary> ''' <value>The resource comment.</value> Public ReadOnly Property Comment As String Get Return comment1 End Get End Property Private ReadOnly comment1 As String ''' <summary> ''' Represents a <see cref="Resource"/> instance that is <c>Nothing</c>. ''' </summary> ''' <value><c>Nothing</c></value> <EditorBrowsable(EditorBrowsableState.Advanced)> Public Shared ReadOnly Property Empty As Resource Get Return Nothing End Get End Property #End Region #Region " Constructors " ''' <summary> ''' Initializes a new instance of the <see cref="Resource"/> class. ''' </summary> ''' <param name="name">The resource name.</param> ''' <param name="data">The resource data.</param> ''' <param name="comment">The resource comment.</param> Public Sub New(ByVal name As String, ByVal data As Object, ByVal comment As String) Me.name1 = name Me.data1 = data Me.comment1 = comment End Sub ''' <summary> ''' Prevents a default instance of the <see cref="Resource"/> class from being created. ''' </summary> Private Sub New() End Sub #End Region #Region " Hidden Methods " ''' <summary> ''' Determines whether the specified System.Object instances are considered equal. ''' </summary> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function Equals(ByVal obj As Object) As Boolean Return MyBase.Equals(obj) End Function ''' <summary> ''' Serves as a hash function for a particular type. ''' </summary> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function GetHashCode() As Integer Return MyBase.GetHashCode End Function ''' <summary> ''' Gets the System.Type of the current instance. ''' </summary> ''' <returns>The exact runtime type of the current instance.</returns> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function [GetType]() As Type Return MyBase.GetType End Function ''' <summary> ''' Returns a String that represents the current object. ''' </summary> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function ToString() As String Return MyBase.ToString End Function #End Region End Class #End Region #Region " Resource(Of T) " ''' <summary> ''' Defines a resource of a .Net managed resource file. ''' </summary> <Serializable> Public NotInheritable Class Resource(Of T) #Region " Properties " ''' <summary> ''' Gets the resource name. ''' </summary> ''' <value>The resource name.</value> Public ReadOnly Property Name As String Get Return Me.name1 End Get End Property Private ReadOnly name1 As String ''' <summary> ''' Gets the resource data. ''' </summary> ''' <value>The resource data.</value> Public ReadOnly Property Data As T Get Return Me.data1 End Get End Property Private ReadOnly data1 As T ''' <summary> ''' Gets the resource type. ''' </summary> ''' <value>The resource type.</value> Public ReadOnly Property Type As Type Get Return GetType(T) End Get End Property ''' <summary> ''' Gets the resource comment. ''' </summary> ''' <value>The resource comment.</value> Public ReadOnly Property Comment As String Get Return comment1 End Get End Property Private ReadOnly comment1 As String #End Region #Region " Constructors " ''' <summary> ''' Initializes a new instance of the <see cref="Resource(Of T)"/> class. ''' </summary> ''' <param name="name">The resource name.</param> ''' <param name="data">The resource data.</param> ''' <param name="comment">The resource comment.</param> Public Sub New(ByVal name As String, ByVal data As T, ByVal comment As String) Me.name1 = name Me.data1 = data Me.comment1 = comment End Sub ''' <summary> ''' Prevents a default instance of the <see cref="Resource(Of T)"/> class from being created. ''' </summary> Private Sub New() End Sub #End Region #Region " Hidden Methods " ''' <summary> ''' Determines whether the specified System.Object instances are considered equal. ''' </summary> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function Equals(ByVal obj As Object) As Boolean Return MyBase.Equals(obj) End Function ''' <summary> ''' Serves as a hash function for a particular type. ''' </summary> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function GetHashCode() As Integer Return MyBase.GetHashCode End Function ''' <summary> ''' Gets the System.Type of the current instance. ''' </summary> ''' <returns>The exact runtime type of the current instance.</returns> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function [GetType]() As Type Return MyBase.GetType End Function ''' <summary> ''' Returns a String that represents the current object. ''' </summary> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function ToString() As String Return MyBase.ToString End Function #End Region End Class #End Region #End Region #Region " Constructors " ''' <summary> ''' Initializes a new instance of the <see cref="ResXManager"/> class. ''' </summary> ''' <param name="resxFilePath">The .Net managed resource filepath.</param> Public Sub New(ByVal resxFilePath As String) Me.filePath1 = resxFilePath End Sub ''' <summary> ''' Prevents a default instance of the <see cref="ResXManager"/> class from being created. ''' </summary> Private Sub New() End Sub #End Region #Region " Public Methods " ''' <summary> ''' Creates the .Net managed resource file. ''' </summary> ''' <param name="replace">if set to <c>true</c>, replaces any existent file.</param> ''' <exception cref="System.Exception"></exception> Public Sub Create(Optional ByVal replace As Boolean = False) Throw New Exception(String.Format("Resource file already exists: {0}", Me.filePath1)) Exit Sub End If Dim resXWritter As ResXResourceWriter = Nothing Try resXWritter = New ResXResourceWriter(Me.filePath1) Using resXWritter resXWritter.Generate() End Using Catch ex As Exception Throw Finally If resXWritter IsNot Nothing Then resXWritter.Close() End If End Try End Sub ''' <summary> ''' Adds a resource into the .Net managed resource file. ''' </summary> ''' <param name="name">The resource name.</param> ''' <param name="data">The resource data.</param> ''' <param name="comment">The resource comment.</param> ''' <exception cref="System.IO.FileNotFoundException">Resource file not found.</exception> ''' <exception cref="System.ArgumentException">A resource with the same name already exists in the table.;name</exception> Public Sub AddResource(ByVal name As String, ByVal data As Object, Optional ByVal comment As String = Nothing) Me.AddResource(replace:=False, name:=name, data:=data, comment:=comment) End Sub ''' <summary> ''' Adds a specified resource of the specified type into the .Net managed resource file. ''' </summary> ''' <typeparam name="T"></typeparam> ''' <param name="name">The resource name.</param> ''' <param name="data">The resource data.</param> ''' <param name="comment">The resource comment.</param> ''' <exception cref="System.IO.FileNotFoundException">Resource file not found.</exception> ''' <exception cref="System.ArgumentException">A resource with the same name already exists in the table.;name</exception> Public Sub AddResource(Of T)(ByVal name As String, ByVal data As T, Optional ByVal comment As String = Nothing) Me.AddResource(replace:=False, name:=name, data:=data, comment:=comment) End Sub ''' <summary> ''' Replaces a resource by the specified name inside the .Net managed resource file. ''' </summary> ''' <param name="name">The resource name.</param> ''' <param name="data">The resource data.</param> ''' <param name="comment">The resource comment.</param> ''' <exception cref="System.IO.FileNotFoundException">Resource file not found.</exception> ''' <exception cref="System.ArgumentException">A resource with the same name already exists in the table.;name</exception> Public Sub ReplaceResource(ByVal name As String, ByVal data As Object, Optional ByVal comment As String = Nothing) Me.AddResource(replace:=True, name:=name, data:=data, comment:=comment) End Sub ''' <summary> ''' Replaces a resource by the specified name of the specified type inside the .Net managed resource file. ''' </summary> ''' <typeparam name="T"></typeparam> ''' <param name="name">The resource name.</param> ''' <param name="data">The resource data.</param> ''' <param name="comment">The resource comment.</param> ''' <exception cref="System.IO.FileNotFoundException">Resource file not found.</exception> ''' <exception cref="System.ArgumentException">A resource with the same name already exists in the table.;name</exception> Public Sub ReplaceResource(Of T)(ByVal name As String, ByVal data As T, Optional ByVal comment As String = Nothing) Me.AddResource(replace:=True, name:=name, data:=data, comment:=comment) End Sub ''' <summary> ''' Finds a resource by the specified name of specified type inside the .Net managed resource file. ''' </summary> ''' <typeparam name="T"></typeparam> ''' <param name="name">The resource name.</param> ''' <param name="stringComparison">The <see cref="StringComparison"/> to compare the resource name.</param> ''' <returns>The resource.</returns> ''' <exception cref="System.IO.FileNotFoundException">Resource file not found.</exception> ''' <exception cref="System.ArgumentException">Resource with the specified name is not found.;name</exception> ''' <exception cref="System.ArgumentException">The specified Type differs from the resource Type.;T</exception> Public Function FindResource(Of T)(ByVal name As String, Optional ByVal stringComparison As StringComparison = StringComparison.OrdinalIgnoreCase) As Resource(Of T) Throw New FileNotFoundException("Resource file not found.", Me.filePath1) Exit Function End If ' Read the ResX file. Dim resX As ResXResourceReader = Nothing Dim res As Resource(Of T) = Nothing Try resX = New ResXResourceReader(Me.filePath1) With {.UseResXDataNodes = True} Using resX For Each entry As DictionaryEntry In resX If entry.Key.ToString.Equals(name, stringComparison) Then Dim node As ResXDataNode = CType(entry.Value, ResXDataNode) res = New Resource(Of T)(name:=node.Name, data:=DirectCast(node.GetValue(DirectCast(Nothing, ITypeResolutionService)), T), comment:=node.Comment) Exit For End If Next entry End Using ' resX Return res Catch ex As Exception Throw Finally If resX IsNot Nothing Then resX.Close() End If End Try End Function ''' <summary> ''' Finds a resource by the specified name inside the .Net managed resource file. ''' </summary> ''' <param name="name">The resource name.</param> ''' <param name="stringComparison">The <see cref="StringComparison"/> to compare the resource name.</param> ''' <returns>The resource.</returns> ''' <exception cref="System.IO.FileNotFoundException">Resource file not found.</exception> ''' <exception cref="System.ArgumentException">Resource with the specified name is not found.;name</exception> ''' <exception cref="System.ArgumentException">The specified Type differs from the resource Type.;T</exception> Public Function FindResource(ByVal name As String, Optional ByVal stringComparison As StringComparison = StringComparison.OrdinalIgnoreCase) As Resource Throw New FileNotFoundException("Resource file not found.", Me.filePath1) Exit Function End If ' Read the ResX file. Dim resX As ResXResourceReader = Nothing Dim res As Resource = Nothing Try resX = New ResXResourceReader(Me.filePath1) With {.UseResXDataNodes = True} Using resX For Each entry As DictionaryEntry In resX If entry.Key.ToString.Equals(name, stringComparison) Then Dim node As ResXDataNode = CType(entry.Value, ResXDataNode) res = New Resource(name:=node.Name, data:=node.GetValue(DirectCast(Nothing, ITypeResolutionService)), comment:=node.Comment) Exit For End If Next entry End Using ' resX Return res Catch ex As Exception Throw Finally If resX IsNot Nothing Then resX.Close() End If End Try End Function ''' <summary> ''' Finds the resources of the specified type inside the .Net managed resource file. ''' </summary> ''' <typeparam name="T"></typeparam> ''' <returns>The resource.</returns> ''' <exception cref="System.IO.FileNotFoundException">Resource file not found.</exception> ''' <exception cref="System.ArgumentException">Resource with the specified name is not found.;name</exception> ''' <exception cref="System.ArgumentException">The specified Type differs from the resource Type.;T</exception> Public Iterator Function FindResources(Of T)() As IEnumerable(Of Resource(Of T)) Throw New FileNotFoundException("Resource file not found.", Me.filePath1) Exit Function End If ' Read the ResX file. Dim resX As ResXResourceReader = Nothing Try resX = New ResXResourceReader(Me.filePath1) With {.UseResXDataNodes = True} Using resX For Each entry As DictionaryEntry In resX Dim node As ResXDataNode = CType(entry.Value, ResXDataNode) If node.GetValue(DirectCast(Nothing, ITypeResolutionService)).GetType Is GetType(T) Then Yield New Resource(Of T)(name:=node.Name, data:=DirectCast(node.GetValue(DirectCast(Nothing, ITypeResolutionService)), T), comment:=node.Comment) End If Next entry End Using ' resX Catch ex As Exception Throw Finally If resX IsNot Nothing Then resX.Close() End If End Try End Function ''' <summary> ''' Removes a resource by the specified name from the .Net managed resource file. ''' </summary> ''' <param name="name">The resource name.</param> ''' <param name="stringComparison">The <see cref="StringComparison"/> to compare the resource name.</param> ''' <exception cref="System.IO.FileNotFoundException">Resource file not found.</exception> ''' <exception cref="System.ArgumentException">Any resource found matching the specified name.;name</exception> Public Sub RemoveResource(ByVal name As String, Optional ByVal stringComparison As StringComparison = StringComparison.OrdinalIgnoreCase) Throw New FileNotFoundException("Resource file not found.", Me.filePath1) Exit Sub End If If Me.FindResource(name, stringComparison) Is Nothing Then Throw New ArgumentException("Any resource found matching the specified name.", "name") Exit Sub End If Dim resources As New List(Of ResXDataNode) Dim resX As ResXResourceReader = Nothing Dim resXWritter As ResXResourceWriter = Nothing Try resX = New ResXResourceReader(Me.filePath1) With {.UseResXDataNodes = True} Using resX For Each entry As DictionaryEntry In resX If Not entry.Key.ToString.Equals(name, stringComparison) Then Dim node As ResXDataNode = CType(entry.Value, ResXDataNode) resources.Add(New ResXDataNode(name:=node.Name, value:=node.GetValue(DirectCast(Nothing, ITypeResolutionService))) With {.Comment = node.Comment}) End If Next entry End Using ' Add the resource in the ResX file. ' Note: This will replace the current ResX file. resXWritter = New ResXResourceWriter(Me.filePath1) Using resXWritter ' Add the retrieved resources into the ResX file. If resources IsNot Nothing Then For Each resourceItem As ResXDataNode In resources resXWritter.AddResource(resourceItem) Next resourceItem End If resXWritter.Generate() End Using ' resXWritter Catch ex As Exception Throw Finally If resX IsNot Nothing Then resX.Close() End If If resXWritter IsNot Nothing Then resXWritter.Close() End If resources.Clear() End Try End Sub #End Region #Region " Private Methods " ''' <summary> ''' Adds or replaces a resource into the .Net managed resource file. ''' </summary> ''' <param name="replace">if set to <c>true</c>, the resource will be replaced.</param> ''' <param name="name">The resource name.</param> ''' <param name="data">The resource data.</param> ''' <param name="comment">The resource comment.</param> ''' <exception cref="System.IO.FileNotFoundException">Resource file not found.</exception> ''' <exception cref="System.ArgumentException">A resource with the same name already exists in the table.;name</exception> Private Sub AddResource(ByVal replace As Boolean, ByVal name As String, ByVal data As Object, ByVal comment As String) Throw New FileNotFoundException("Resource file not found.", Me.filePath1) Exit Sub End If Dim resources As New List(Of ResXDataNode) Dim resX As ResXResourceReader = Nothing Dim resXWritter As ResXResourceWriter = Nothing Try resX = New ResXResourceReader(Me.filePath1) With {.UseResXDataNodes = True} Using resX For Each entry As DictionaryEntry In resX If Not replace AndAlso entry.Key.ToString.Equals(name, StringComparison.OrdinalIgnoreCase) Then Throw New ArgumentException("A resource with the same name already exists in the table.", "name") Else Dim node As ResXDataNode = CType(entry.Value, ResXDataNode) resources.Add(New ResXDataNode(name:=node.Name, value:=node.GetValue(DirectCast(Nothing, ITypeResolutionService))) With {.Comment = node.Comment}) End If Next entry End Using ' Add the resource in the ResX file. ' Note: This will replace the current ResX file. resXWritter = New ResXResourceWriter(Me.filePath1) Using resXWritter ' Add the retrieved resources into the ResX file. If resources IsNot Nothing Then For Each resourceItem As ResXDataNode In resources resXWritter.AddResource(resourceItem) Next resourceItem End If ' Add the specified resource into the ResX file. resXWritter.AddResource(New ResXDataNode(name, data) With {.Name = name, .Comment = comment}) resXWritter.Generate() End Using ' resXWritter Catch ex As Exception Throw Finally If resX IsNot Nothing Then resX.Close() End If If resXWritter IsNot Nothing Then resXWritter.Close() End If resources.Clear() End Try End Sub ''' <summary> ''' Gets all the resources contained in the .Net managed resource file. ''' </summary> ''' <returns>IEnumerable(Of Resource).</returns> Private Iterator Function GetResources() As IEnumerable(Of Resource) ' Read the ResX file. Using resX As New Resources.ResXResourceReader(Me.filePath1) With {.UseResXDataNodes = True} For Each entry As DictionaryEntry In resX Dim node As ResXDataNode = CType(entry.Value, ResXDataNode) Yield New Resource(name:=node.Name, data:=node.GetValue(DirectCast(Nothing, ITypeResolutionService)), comment:=node.Comment) Next entry End Using ' resX End Function #End Region #Region " Hidden Methods " ''' <summary> ''' Determines whether the specified System.Object instances are considered equal. ''' </summary> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function Equals(ByVal obj As Object) As Boolean Return MyBase.Equals(obj) End Function ''' <summary> ''' Serves as a hash function for a particular type. ''' </summary> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function GetHashCode() As Integer Return MyBase.GetHashCode End Function ''' <summary> ''' Gets the System.Type of the current instance. ''' </summary> ''' <returns>The exact runtime type of the current instance.</returns> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function [GetType]() As Type Return MyBase.GetType End Function ''' <summary> ''' Returns a String that represents the current object. ''' </summary> <EditorBrowsable(EditorBrowsableState.Never)> Public Shadows Function ToString() As String Return MyBase.ToString End Function #End Region End Class