binär serialisiertes Setting mit einem Default-Wert

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von VB1963.

    binär serialisiertes Setting mit einem Default-Wert

    Hallo Community!

    Folgender Codeausschnitt wirft mir mit leeren Setting Dim x = My.Settings.Tester ohne Try Catch in der Zeile 11 eine ArgumentException:
    "Die Tester-Eigenschaft konnte nicht aus ihrem Standardwert erstellt werden. Fehlermeldung: Der binäre Stream "224" enthält keinen gültigen BinaryHeader.
    Möglicherweise ist der Stream ungültig oder die Objektversion wurde zwischen der Serialisierung und der Deserialisierung geändert."


    VB.NET-Quellcode

    1. Namespace My
    2. Partial Friend NotInheritable Class MySettings
    3. Private Const _DefaultTester = "Das ist eine Voreinstellung"
    4. <Global.System.Configuration.UserScopedSettingAttribute(), _
    5. Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
    6. Global.System.Configuration.DefaultSettingValueAttribute(_DefaultTester), _
    7. Global.System.Configuration.SettingsSerializeAs(System.Configuration.SettingsSerializeAs.Binary)> _
    8. Public Property Tester As String
    9. Get
    10. 'Try
    11. Return CType(Me("Tester"), String)
    12. 'Catch ex As Exception
    13. ' Return _DefaultTester
    14. 'End Try
    15. End Get
    16. Set(ByVal value As String)
    17. Me("Tester") = value
    18. End Set
    19. End Property
    20. End Class
    21. End Namespace

    kann man so etwas ohne Try Catch realisieren?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VB1963“ ()

    Muss es Binary sein? Ohne Binary funktioniert es.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Oder Du konvertierst dies

    VB1963 schrieb:

    VB.NET-Quellcode

    1. Private Const _DefaultTester = "Das ist eine Voreinstellung"
    explizit nach Byte-Array?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Rod Danke für deinen Input, damit ist mir ein Lichtlein aufgegangen ;)
    Ich habe das Ganze jetzt so gelöst:

    VB.NET-Quellcode

    1. Imports System.Security.Cryptography
    2. Imports System.IO
    3. Imports System.Text
    4. Namespace My
    5. Partial Friend NotInheritable Class MySettings
    6. Private Key() As Byte = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    7. Private IV() As Byte = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    8. Private Const _DefaultVersuch = "Das ist eine Voreinstellung"
    9. <Global.System.Configuration.UserScopedSettingAttribute(), _
    10. Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
    11. Global.System.Configuration.DefaultSettingValueAttribute(_DefaultVersuch)> _
    12. Public Property Versuch As String
    13. Get
    14. Dim _Value = CType(Me("Versuch"), String)
    15. If _Value = _DefaultVersuch Then Return _Value
    16. Return DecryptStringFromBytes(Encoding.Default.GetBytes(_Value), Key, IV)
    17. End Get
    18. Set(ByVal value As String)
    19. Me("Versuch") = Encoding.Default.GetString(EncryptStringToBytes(value, Key, IV))
    20. End Set
    21. End Property
    22. Shared Function DecryptStringFromBytes(ByVal cipherText() As Byte, ByVal Key() As Byte, ByVal IV() As Byte) As String
    23. '...
    24. End Function
    25. Shared Function EncryptStringToBytes(ByVal plainText As String, ByVal Key() As Byte, ByVal IV() As Byte) As Byte()
    26. '...
    27. End Function
    28. End Class
    29. End Namespace

    Die Verschlüsselungsroutinen habe ich einfach von AesManaged-Klasse herausgenommen.
    Damit sind die Settingsdaten ordentlich verschleiert abgespeichert.
    Ich werde das jetzt versuchen auch mit anderen Datentypen umzusetzen...

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „VB1963“ ()

    Hi
    serialisiere doch einfach in deinen eigenen Stream. Dazu erzeugst du einen CryptoStream und serialisierst dorthin z.B. mithilfe des BinaryFormatters.
    Sei dir aber bewusst, dass auch dann die Sicherheit nur geringfügig besser ist, als wenn du es gleich sichtbar speicherst. Die Daten stehen ja noch immer direkt im Quellcode oder Resourcen drin und sind daher einfach auszulesen.

    Gruß
    ~blaze~
    Hi @~blaze~:
    Probieren ist fehlgeschlagen... :S
    Kannst du mir deinen Vorschlag nochmals detaillierter und genauer erklären.
    Ich habe mit der Kombination Cryptostream und Serialisieren mithilfe BinaryFormatter noch so meine Probleme...

    So, jetzt habe ich nach langen Grübeln und Studieren folgendes zusammengestellt (ist aber noch ungetestet...):

    VB.NET-Quellcode

    1. Imports System.Runtime.Serialization.Formatters.Binary
    2. Imports System.Security.Cryptography
    3. Imports System.IO
    4. Imports System.Text
    5. Namespace My
    6. Partial Friend NotInheritable Class MySettings
    7. Private Key() As Byte = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    8. Private IV() As Byte = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    9. Private Const _DefaultVersuch = "Das ist eine Voreinstellung"
    10. <Global.System.Configuration.UserScopedSettingAttribute(), _
    11. Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
    12. Global.System.Configuration.DefaultSettingValueAttribute(_DefaultVersuch)> _
    13. Public Property Versuch As String
    14. Get
    15. Dim _Value = CType(Me("Versuch"), String)
    16. If _Value = _DefaultVersuch Then Return _Value
    17. '
    18. Using ms As New MemoryStream(Encoding.Default.GetBytes(_Value))
    19. Dim aes As New AesManaged()
    20. Using crs As New CryptoStream(ms, aes.CreateDecryptor(Key, IV), CryptoStreamMode.Read)
    21. Dim binfmt As New BinaryFormatter()
    22. Return DirectCast(binfmt.Deserialize(crs), String)
    23. End Using
    24. End Using
    25. End Get
    26. Set(ByVal value As String)
    27. Using ms As New MemoryStream()
    28. Dim aes As New AesManaged()
    29. Using crs As New CryptoStream(ms, aes.CreateEncryptor(Key, IV), CryptoStreamMode.Write)
    30. Dim binfmt As New BinaryFormatter()
    31. Me("Versuch") = DirectCast(binfmt.Serialize(crs, Value), String)
    32. End Using
    33. End Using
    34. End Set
    35. End Property
    36. End Class
    37. End Namespace

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB1963“ ()

    So ähnlich war's gedacht. Ich hätte einfach eine komplett neue Klasse dafür angefangen und dann die Settings direkt als Properties modelliert. Anschließend hätte ich die Klasse mit dem SerializableAttribute-Attribut versehen und eine Save- und statische Load-Methode eingeführt. Save serialisiert die gesamte Klasse in einen Stream, der als Parameter angegeben wird und Load lädt sie aus einem angegebenen Stream. Zusätzlich dazu hast du eine weitere Klasse, die die Einstellungen sicher speichert und dann eben den CryptoStream an die Load und Save-Methoden übergibt. Serialisiert werden können dann eben alle Objekte, die serialisierbar sind.
    Tut zwar keine Sache zum eigentlichen Problem, aber wenn du diese Zugriffe über den Namen möchtest, kannst du natürlich auch ein Dictionary verwenden (z.B. kannst du die Properties über den System.ComponentModel.TypeDescriptor abrufen und dann ein Dictionary(Of String, PropertyDescriptor) dazu verwenden, um auf die einem Namen zugeordneten Properties zuzugreifen und diese dann per PropertyDescriptor.GetValue und PropertyDescriptor.SetValue anzusteuern. instance ist in deinem Fall dann eben Me).

    Gruß
    ~blaze~
    Danke für deine ausführlichen Erklärungen.
    Mit einer eigenen Klasse zum Serialisieren, glaube ich, ist im Entwicklerbuch sogar ausführlich beschrieben.
    Das mit dem PropertyDescriptor ist für mich Neuland - das muss ich mir einmal genauer ansehen...

    Gruß
    VB1963
    Hallo VBP-Community!

    Wen es interessiert, ich habe das obige Problem jetzt folgend gelöst.
    Dazu sind 2 Klassen erforderlich:
    • ein ApplicationSettings-Wrapper, der von ApplicationSettingsBase beerbt wird
    • und ein eigens erstellter SettingsProvider, der von SettingsProvider beerbt wird.
    siehe dazu Näheres hier und hier

    CustomSettings-Wrapper:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Configuration
    2. Imports System.ComponentModel
    3. <SettingsProvider(GetType(CryptoSettingsProvider))> _
    4. Public Class CustomSettings
    5. Inherits ApplicationSettingsBase
    6. 'Public Sub New()
    7. ' AddHandler Me.SettingChanging, AddressOf Me.SettingChangingEventHandler
    8. ' AddHandler Me.SettingsSaving, AddressOf Me.SettingsSavingEventHandler
    9. 'End Sub
    10. 'Private Sub SettingChangingEventHandler(sender As Object, e As SettingChangingEventArgs)
    11. 'End Sub
    12. 'Private Sub SettingsSavingEventHandler(sender As Object, e As CancelEventArgs)
    13. 'End Sub
    14. <UserScopedSettingAttribute(), DefaultSettingValueAttribute("00:00:00")> _
    15. Public Property VisitDuration As TimeSpan
    16. Get
    17. Return CType(Me("VisitDuration"), TimeSpan)
    18. End Get
    19. Set(ByVal value As TimeSpan)
    20. Me("VisitDuration") = value
    21. End Set
    22. End Property
    23. <UserScopedSettingAttribute(), DefaultSettingValueAttribute("PaleGreen")> _
    24. Public Property ControlBackcolor As Drawing.Color
    25. Get
    26. Return CType(Me("ControlBackcolor"), Drawing.Color)
    27. End Get
    28. Set(ByVal value As Drawing.Color)
    29. Me("ControlBackcolor") = value
    30. End Set
    31. End Property
    32. <UserScopedSettingAttribute()> _
    33. Public Property MyBytes() As Byte()
    34. Get
    35. Return CType(Me("MyBytes"), Byte())
    36. End Get
    37. Set(value As Byte())
    38. Me("MyBytes") = value
    39. End Set
    40. End Property
    41. <UserScopedSettingAttribute(), DefaultSettingValueAttribute("32321111")> _
    42. Public Property TestData As Decimal
    43. Get
    44. Return CType(Me("TestData"), Decimal)
    45. End Get
    46. Set(ByVal value As Decimal)
    47. Me("TestData") = value
    48. End Set
    49. End Property
    50. <UserScopedSettingAttribute(), DefaultSettingValueAttribute("Hallo!")> _
    51. Public Property TestString As String
    52. Get
    53. Return CType(Me("TestString"), String)
    54. End Get
    55. Set(ByVal value As String)
    56. Me("TestString") = value
    57. End Set
    58. End Property
    59. End Class
    CryptoSettings-Provider:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Configuration
    2. Imports System.ComponentModel
    3. Imports System.Reflection
    4. Imports System.IO
    5. Imports System.Security.Cryptography
    6. Imports System.Collections.Specialized
    7. Imports System.Runtime.Serialization.Formatters.Binary
    8. Public Class CryptoSettingsProvider
    9. Inherits SettingsProvider
    10. Private Datas As Dictionary(Of String, Object)
    11. Private DataFile As String
    12. Public Sub New()
    13. ApplicationName = Assembly.GetExecutingAssembly.GetName.Name
    14. Datas = New Dictionary(Of String, Object)()
    15. DataFile = getFileName()
    16. LoadSettingsFromFile()
    17. End Sub
    18. Public Overrides Sub Initialize(name As String, config As NameValueCollection)
    19. MyBase.Initialize(ApplicationName, config)
    20. End Sub
    21. Public Overrides Property ApplicationName As String
    22. Public Overrides ReadOnly Property Name As String
    23. Get
    24. Return "CryptoSettingsProvider"
    25. End Get
    26. End Property
    27. Public Overrides Function GetPropertyValues(context As SettingsContext, collection As SettingsPropertyCollection) As SettingsPropertyValueCollection
    28. Dim col As New SettingsPropertyValueCollection()
    29. For Each prp As SettingsProperty In collection
    30. Dim prpValue As New SettingsPropertyValue(prp)
    31. prpValue.IsDirty = False
    32. If Datas.ContainsKey(prp.Name) Then
    33. prpValue.SerializedValue = Datas(prp.Name)
    34. prpValue.PropertyValue = Datas(prp.Name)
    35. End If
    36. col.Add(prpValue)
    37. Next
    38. Return col
    39. End Function
    40. Public Overrides Sub SetPropertyValues(context As SettingsContext, collection As SettingsPropertyValueCollection)
    41. For Each prpValue As SettingsPropertyValue In collection
    42. Datas(prpValue.Name) = prpValue.PropertyValue ' wenn Item nicht vorhanden ist, wird Item automatisch angefügt
    43. Next
    44. EncryptAndSaveDatas(DataFile, Datas)
    45. End Sub
    46. Private Function getFileName() As String
    47. Return Path.Combine(Application.StartupPath, String.Concat(ApplicationName, ".exe.config.dat"))
    48. End Function
    49. Private Sub LoadSettingsFromFile()
    50. Dim fi = New FileInfo(DataFile)
    51. If fi.Exists Then Datas = DecryptAndLoadDatas(DataFile)
    52. End Sub
    53. #Region "Cryptography"
    54. Private Key() As Byte = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    55. Private IV() As Byte = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    56. Private Sub EncryptAndSaveDatas(DataFile As String, Datas As Dictionary(Of String, Object))
    57. Using fs As Stream = File.Create(DataFile)
    58. Dim aes As New AesManaged()
    59. Using crs As Stream = New CryptoStream(fs, aes.CreateEncryptor(Key, IV), CryptoStreamMode.Write)
    60. Dim binfmt As New BinaryFormatter()
    61. binfmt.Serialize(crs, Datas)
    62. End Using
    63. End Using
    64. End Sub
    65. Private Function DecryptAndLoadDatas(DataFile As String) As Dictionary(Of String, Object)
    66. Using fs As Stream = File.Open(DataFile, FileMode.Open)
    67. Dim aes As New AesManaged()
    68. Using crs As Stream = New CryptoStream(fs, aes.CreateDecryptor(Key, IV), CryptoStreamMode.Read)
    69. Dim binfmt As New BinaryFormatter()
    70. Return CType(binfmt.Deserialize(crs), Dictionary(Of String, Object))
    71. End Using
    72. End Using
    73. End Function
    74. #End Region
    75. End Class

    In Zeile #4 des ersten Listings wird der Provider in die Wrapperklasse eingebunden.
    Dieser Provider ermöglicht das Abspeichern der Settings in verschlüsselter Form.
    Die Daten werden im Arbeitsverzeichnis der Anwendung in einer eigenen Datei DeineAnwendung.exe.config.dat gehalten.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private WithEvents mySettings As New CustomSettings
    3. Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    4. mySettings.Save() 'muss explizit durchgeführt werden!
    5. End Sub
    6. Private Sub Form1_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
    7. Dim Dauer = mySettings.VisitDuration
    8. mySettings.VisitDuration = TimeSpan.Parse("00:21:25")
    9. Dim Farbe = mySettings.ControlBackcolor
    10. mySettings.ControlBackcolor = Drawing.Color.AliceBlue
    11. Dim myBytes = mySettings.MyBytes
    12. mySettings.MyBytes = {111, 121, 131, 141, 151, 161, 171, 181, 191, 100}
    13. '
    14. 'manuelles Binding ist erforderlich!
    15. '
    16. TextBox1.DataBindings.Add(New Binding("Text", mySettings, "TestString", True, DataSourceUpdateMode.OnPropertyChanged))
    17. NumericUpDown1.DataBindings.Add(New Binding("Value", mySettings, "TestData", True, DataSourceUpdateMode.OnPropertyChanged))
    18. End Sub
    19. End Class

    In Zeile #3 wird die neue Settingsklasse deklariert.

    Der Settingseditor gilt für diese Wrapper-Klasse nicht!
    Die Property's sind im Editor und in der user.config nicht aufgelistet.
    Das Speichern der Settings ist manuell durchzuführen. Hier gilt das automatische Abspeichern der Settings beim Schließen der Anwendung nicht!
    Die Property's sind genauso bindbar, wie bei den herkömmlichen Settings - aber die Bindung muss manuell erstellt werden!

    lg
    VB1963
    Dateien

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „VB1963“ ()

    Hmm - das gefällt mir nicht super, dass man dafür so viel individuell programmieren, und ausserdem einige Features der Settings aufgeben muß - etwa SettingsBinding im Designer.
    Da kann man ja bald die Settings auch bleiben lassen, und seine Einstellungen stattdessen in einem globalen Objekt ablegen, und dieses in einen CryptoStream serialisieren.
    Ja, der Comfort des Settingseditors ist hier leider verloren gegangen... :S
    Der eigentliche Programmieraufwand:
    *) wie die explizite Angabe der gewünschten Property's im Settings-Wrapper, wobei der Property-Rumpf immer der selbe ist,
    *) und die 1 Zeile Code beim Binden je Property - wenn man das braucht
    *) ja und das Speichern beim Schließen der Anwendung
    hält sich meiner Meinung nach, wenn die Klassen einmal eingebunden sind, in erträglichen Grenzen.
    Sonnst ist das Verhalten der Settings im Code gleich wie zu den My.Settings zu betrachten.
    Ob das jetzt den Aufwand wert ist, um seine Settings eigentlich nur verschlüsselt zu speichern, ist eine Frage für jeden selbst...
    Obiges Beispiel zeigt einen Weg, wie man machen könnte...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB1963“ ()

    Hallo Community!
    Es hat mich keine Ruhe gelassen :)
    Ich habe nach Einwand von @ErfinderDesRades: den CryptoSettingsProvider noch etwas weiter modifiziert.
    Die Wrapperklasse wird nicht mehr dazu gebraucht und dafür ist der Comfort vom Settingseditor wieder nutzbar.
    Man braucht den eigenen Provider einfach nur mehr im Settingseditor bei beliebigen Einstellungen als Provider angeben. (siehe Bild im Anhang)
    Der Editor versieht den jeweiligen Eintrag mit dem richtigen Provider-Attribut.
    Siehe dazu folgenden Codeauszug aus der generierten MySettings-Klasse...
    Spoiler anzeigen

    VB.NET-Quellcode

    1. <Global.System.Configuration.UserScopedSettingAttribute(), _
    2. Global.System.Configuration.SettingsProviderAttribute(GetType(CryptoSettingsProvider)), _
    3. Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
    4. Global.System.Configuration.DefaultSettingValueAttribute("Hallo!")> _
    5. Public Property Versuch() As String
    6. Get
    7. Return CType(Me("Versuch"),String)
    8. End Get
    9. Set
    10. Me("Versuch") = value
    11. End Set
    12. End Property
    13. <Global.System.Configuration.UserScopedSettingAttribute(), _
    14. Global.System.Configuration.SettingsProviderAttribute(GetType(CryptoSettingsProvider)), _
    15. Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
    16. Global.System.Configuration.DefaultSettingValueAttribute("50")> _
    17. Public Property TestValue() As Decimal
    18. Get
    19. Return CType(Me("TestValue"),Decimal)
    20. End Get
    21. Set
    22. Me("TestValue") = value
    23. End Set
    24. End Property
    25. <Global.System.Configuration.UserScopedSettingAttribute(), _
    26. Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
    27. Global.System.Configuration.DefaultSettingValueAttribute("das ist ein ganz normales Setting!")> _
    28. Public Property NormalSetting() As String
    29. Get
    30. Return CType(Me("NormalSetting"),String)
    31. End Get
    32. Set
    33. Me("NormalSetting") = value
    34. End Set
    35. End Property

    Man kann auch die ganze MySettings-Klasse mit dem Provider versehen.
    Einfach im Editor auf Code anzeigen gehen und die Klasse mit dem Provider erweitern:

    VB.NET-Quellcode

    1. <Global.System.Configuration.SettingsProviderAttribute(GetType(CryptoSettingsProvider))> _
    2. Partial Friend NotInheritable Class MySettings
    3. End Class

    Das automatische Speichern ist jetzt auch wieder möglich!


    Das Binding muss aber leider immer noch manuell via Code erfolgen :S (da habe ich noch keine Lösung dafür gefunden...)
    Wenn man via Eigenschaften-Editor ein Control binden will, erscheint immer eine Meldung von VS2010? (siehe Bild im Anhang)
    Vielleicht kann mir hier jemand einen Tipp geben...

    lg
    VB1963
    Bilder
    • Provider für Settings.PNG

      33,42 kB, 1.776×221, 355 mal angesehen
    • Meldung von VS2010.PNG

      31,23 kB, 1.199×248, 116 mal angesehen
    Dateien

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB1963“ ()

    Nach meinen Recherchen ergibt sich jetzt folgendes:
    Wenn der Provider klassenweit angegeben wird kann ohne Weiteres das Binding der Propertys im Editor erfolgen.

    VB.NET-Quellcode

    1. <Global.System.Configuration.SettingsProviderAttribute(GetType(CryptoSettingsProvider))> _
    2. Partial Friend NotInheritable Class MySettings
    3. End Class
    Die Meldung tritt nur bei der Providerangabe eines beliebigen Setting-Eintrages auf.
    Wenn man vorher das Binding angibt und erst nachher die vereinzelten Setting-Einträge mit dem Provider versieht funktioniert es?
    Es kommen dann aber 2 Warnmeldungen die beim Öffnen der Form im Editormodus, die das selbige wieder melden aber sonnst nichts verursachen... :whistling:

    Problemlösung: benutzerdefinierter Settingsprovider und Datenbindung

    Der folgende Hinweis hat geholfen:

    Koopakiller (MSDN-Forum) schrieb:

    Es läuft letzten Endes darauf hinaus den Provider in eine eigene Klassenbibliothek zu packen. Nachdem ich das tat funktionierte es.
    Ich denke mal, das es sich hierbei um einen "einfachen" Bug im Designer handelt.

    Wichtig ist hier noch anzumerken, dass die Klasse SettingsProvider mit Public modifiziert wird. siehe Näheres hier
    Bzw. im Sourcecode-Austausch habe ich auch den Provider und Abwandlungen davon eingestellt: UserSettingsProvider (Persistieren von UserSettings)
    Wer es braucht oder interessiert ist anbei ein fertiges CryptoSettingsProvider-Library in einer Testumgebung...
    Dateien

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „VB1963“ ()