user10771503
user10771503

Reputation:

store setting in relative path to executable aplication

I am developing an application to run from USB, is it like a dock/launcher application but I have a problem.

I want to use My.Settings class to save my app settings, but it saves the setting file in AppData folder e.g. C:\Users\<user_name>\AppData\Local\...\...\user.config

I don't want that. I want to save in a path and name of my defined, e.g. My.Application.Info.DirectoryPath & "\Settings.xml"

How can I achieve this?

Update Example of final XML:

<?xml version="1.0" encoding="utf-8"?>
<conf>
    <pos>1</pos>
    <btn index="1" value="D:\League of Legends\" perm="true">LeagueClient.exe</btn>
    <btn index="2" value="D:\RuneLite\" perm="false">RuneLite.exe</btn>
    <btn index="3" value="" perm="false"></btn>
    <btn index="4" value="" perm="false"></btn>
</conf>

Full project in Github coming soon!!!

Upvotes: 0

Views: 86

Answers (2)

Visual Vincent
Visual Vincent

Reputation: 18330

XML Serialization can be used for this, and is actually fairly straightforward. All you need to do is design one or more classes for your data, then apply the appropriate attributes (their name are in the form Xml...Attribute) in order to serialize them the way you want.

In this setup I've used four different attributes:

  • XmlElement - Usually the most common one. Specifies that a property will be serialized as an element of its own. The resulting name can be customized by setting the ElementName parameter in the constructor.

    If used on lists or arrays, it applies to each item in the collection.

  • XmlRoot - Pretty much the same as XmlElement, but used for the root element (the class itself).

  • XmlAttribute - Specifies that a property will be serialized as an attribute (name="value") applied to the parent object, instead of as an element inside it.

  • XmlText - Specifies that a property's value will be serialized as the contents between the tags of the parent object (i.e. <object>property value</object>).

Imports System.IO
Imports System.Xml
Imports System.Xml.Serialization

<XmlRoot(ElementName:="conf")>
Public Class Config

    <XmlElement(ElementName:="pos")>
    Public Property Position As Integer

    <XmlElement(ElementName:="btn")>
    Public Property Buttons As New List(Of ConfigButton)

    Public Sub New()
    End Sub

    Public Sub New(ByVal Position As Integer)
        Me.Position = Position
    End Sub

    Public Shared Function Load(ByVal File As String) As Config
        Using FStream As New FileStream(File, FileMode.Open, FileAccess.Read, FileShare.Read)
            Dim Serializer As New XmlSerializer(GetType(Config))
            Return Serializer.Deserialize(FStream)
        End Using
    End Function

    Public Sub Save(ByVal File As String)
        Using FStream As New FileStream(File, FileMode.Create, FileAccess.Write, FileShare.None)
            Dim Serializer As New XmlSerializer(GetType(Config))
            Serializer.Serialize(FStream)
        End Using
    End Sub
End Class
Public Class ConfigButton

    <XmlText()>
    Public Property DisplayName As String

    <XmlAttribute("index")>
    Public Property Index As Integer

    <XmlAttribute("perm")>
    Public Property Perm As Boolean

    <XmlAttribute("value")>
    Public Property Value As String

    Public Sub New()
    End Sub

    Public Sub New(ByVal DisplayName As String, ByVal Value As String, ByVal Index As Integer, ByVal Perm As Boolean)
        Me.DisplayName = DisplayName
        Me.Value = Value
        Me.Index = Index
        Me.Perm = Perm
    End Sub
End Class

Usage example:

Private cfg As Config

'
'Loading the config.
'

Private Sub Form1_Load(sender As Object, e As EventArgs) Handled MyBase.Load
    If File.Exists("config.xml") Then
        cfg = Config.Load("config.xml")
    Else
        cfg = New Config()
    End If
End Sub

'
'Saving the config.
'

Private Sub Form1_FormClosed(sender As Object, e As EventArgs) Handles Me.FormClosed
    cfg.Save("config.xml")
End Sub

Adding a button:

cfg.Buttons.Add(New ConfigButton("RuneLite.exe", "D:\RuneLite\", 2, False))

Iterating buttons:

For Each btn As ConfigButton In cfg.Buttons
    MessageBox.Show(btn.DisplayName)
Next

Removing a button at a specific index:

'Removes the fourth button.
cfg.Buttons.RemoveAt(3)

Upvotes: 0

user10771503
user10771503

Reputation:

Work way for me :

Imports System.IO
Imports System.Xml

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ValConfFile()
    End Sub
    Public Sub ValConfFile()
        If File.Exists("config.xml") = False Then : CreateConfXML() : End If
    End Sub
    Public Sub CreateConfXML()
        Dim obj As Object
        Dim archivo As Object
        Dim x As Integer = 1
        obj = CreateObject("Scripting.FileSystemObject")
        archivo = obj.CreateTextFile("config.xml", True)
        archivo.WriteLine("<?xml version='1.0' encoding='utf-8'?>")
        archivo.WriteLine("<conf>")
        archivo.WriteLine("<pos>1</pos>")
        For x = 1 To 4
            archivo.WriteLine("<btn index='" & CStr(x) & "' value='' perm='false'></btn>")
        Next
        archivo.WriteLine("</conf>")
        archivo.Close()
    End Sub
End Class

Upvotes: 1

Related Questions