Writing settings to a file??? XML control???

N

Noozer

I need to keep my application settings in a file that users can
copy/backup/etc.

Before I start using the old INI file standard, is there any easy way to use
XML files to hold application settings?

What is the standard method of saving user settings for VB.Net apps?
 
E

Earl

You want to create an application configuration file, "yourappname.config".
In the MSDN, check out configuration files > application configuration
files.
 
C

Chris, Master of All Things Insignificant

That only works if you don't want to save user settings they choose inside
the program. You can't write to "application.config" files on the fly like
you could an ini file. I wrote my own settingshandler class to handle the
xml settings.

Chris
 
N

Noozer

Thanks!


Earl said:
You want to create an application configuration file, "yourappname.config".
In the MSDN, check out configuration files > application configuration
files.
 
C

Chris, Master of All Things Insignificant

See my post. There is no class that I know of that will do what you want.
Search around codeproject and such, I've seen examples around for doing it
though.

Chris
 
E

Earl

Well, XML is obviously not a "read-only" file. Except for the fact that you
want it to be read-only (binary?), you can easily save those settings to the
application.config file.
 
E

Earl

I'm not sure what you are saying ... that you cannot save to the config file
on the fly? Surely you can, it's simply an XML file.
 
H

Herfried K. Wagner [MVP]

Noozer said:
I need to keep my application settings in a file that users can
copy/backup/etc.

Before I start using the old INI file standard, is there any easy way to
use
XML files to hold application settings?

What is the standard method of saving user settings for VB.Net apps?


People tend to prefer XML, but I still prefer old-style INI formats for
simple settings, because human-readability is better and it's harder to make
the file invalid.

You'll find some links to articles, code, and libraries for storing user
settings here:

Storing and loading user preferences
<URL:http://dotnet.mvps.org/dotnet/faqs/?id=userpreferences&lang=en>
 
C

Cor Ligthert

Noozer,

Just use a dataset when it are your own application settings. (Not the users
settings for that is in my opinion the registry)

You can read that from disk with ds.readXML(path) and write it with
ds.writeXML(path)

Getting the elements using the datatable/datarow methods is than much easier
than by instance a nodereader.

Just my thought,

Cor
 
C

Cor Ligthert

Herfried,

"Herfried K. Wagner [MVP]"
People tend to prefer XML, but I still prefer old-style INI formats for
simple settings, because human-readability is better and it's harder to
make the file invalid.
How you can say "human-readability" is better, are you not our link
providing computer.

You know that I know better, however I have forever hated those Ini files. I
even find the registry more readable, so to say human-readability is in my
opinion very much a matter of taste. As you know I prefer XML for
application settings and the registry for user settings and that as well for
readability.

Cor
 
N

Noozer

My application isn't allowed to write to the application.config file.

How many users do you let access your sourcecode and compile their own
settings into the app?

Microsoft provides the application read only access to the
application.config file.
 
N

Noozer

Cor Ligthert said:
Noozer,

Just use a dataset when it are your own application settings. (Not the users
settings for that is in my opinion the registry)

You can read that from disk with ds.readXML(path) and write it with
ds.writeXML(path)

Getting the elements using the datatable/datarow methods is than much easier
than by instance a nodereader.

Just my thought,

Cor
 
N

Noozer

I need to keep my application settings in a file that users can
Just use a dataset when it are your own application settings. (Not the users
settings for that is in my opinion the registry)

You can read that from disk with ds.readXML(path) and write it with
ds.writeXML(path)

Getting the elements using the datatable/datarow methods is than much easier
than by instance a nodereader.

This is what I'm doing... Just getting my head around the use of the Dataset
now.

I can't use the registry as it doesn't follow the user and they don't always
sit at the same machine. They also don't have the ability to import data
into the registry. So, a portable configuration file is the next best thing.
 
E

Earl

I'm not sure why your "application isn't allowed to write to the app.config
file", unless you mean a decision by someone in your company. There seems to
be a lot of misguided understanding about how app.config works.

Your app should determine which settings are allowed -- without code to
accomodate the .config file, whatever the user could even maliciously put in
there is pointless gibberish and has no effect whatsoever. It certainly has
nothing to do with the functioning of your code or your app unless you code
your app to respond to it. That one is on the developer.

But one use that I have for app.config is to let my users write which SQL
server they are connected to (obviating the need to use SQLDMO). Not sure
why you would not want to allow your app to do something similar.

In any event, no, "Microsoft does not "provide the application read-only
access to the application config file". App.config (renamed to your
exe.config on compile) loads into a cache when the application loads, but it
CAN be modified during running of the program -- it's simply a static XML
file. I do exactly this in one of my apps. However, although the settings
are changed, the program will NOT reload those settings until the app is
restarted.

You can take another tack on the same scenario that WILL allow you to reload
user settings while the program is running, by writing those user settings
to a file.config which you name whatever you like. You can then write and
read to your heart's content and make changes on the fly and reload changes
on the fly.
 
C

Cor Ligthert

Noozer,

I made a little sample for you which I typed in this message, so watch typos

To create
\\\
Dim ds as new dataset
dim dt as new datatable
dt.columns.add("TheLastDate",gettype(system.datetime))
dt.rows.add(dt.newrow)
ds.tables.add(dt)
dt.rows(0)("TheLastDate") = date.Now
ds.writeXML("C:\path")
///
To use
\\\
ds.read(XML"C:\path")
dim mydate as datetime = ds.tables(0).rows(0)("TheLastDate")
///

I hope this helps?

Cor
 
N

Noozer

To create
\\\
Dim ds as new dataset
dim dt as new datatable
dt.columns.add("TheLastDate",gettype(system.datetime))
dt.rows.add(dt.newrow)
ds.tables.add(dt)
dt.rows(0)("TheLastDate") = date.Now
ds.writeXML("C:\path")
///
To use
\\\
ds.read(XML"C:\path")
dim mydate as datetime = ds.tables(0).rows(0)("TheLastDate")
///

I hope this helps?

Very helpful... It works great!!! I do have one more question though...

It would be great to be able to store object properties so I tried the code
included below, but it doesn't work. The program complains that the
"Specified cast is not valid". Since the data was written out with a
specific data type, why wouldn't the cast be valid when reading it back in?
I can break these properties down to simple data types, but I'd rather do it
this way if it's possible.

'Write settings...
Private Sub Write()

'Declare dataset objects
dim ds as new dataset("Settings")
dim dt as new datatable("Textbox")

'Add columns to the table
dt.columns.add("Foreground", GetType(System.Drawing.Color))
dt.columns.add("Font", gettype(System.Drawing.Font))

'Add a row to the table
dt.Rows.Add(dt.NewRow)

'Add the table to the dataset
ds.Tables.Add(dt)

'Update data in table
dt.Rows(0)("Foreground") = txtBox.Forecolor
dt.Rows(0)("Font") = txtBox.Font

'Write dataset to disk
ds.WriteXML("C:\File.xml")

'Destroy objects
dt = Nothing
ds = Nothing

End Sub

Private Sub Read()
'Declare objects
Dim ds as Dataset
Dim dt as Datatable

txtBox.Font = ds.Tables("Textbox").Rows(0)("Font")
txtBox.ForeColor = ds.Tables("Textbox").Rows(0)("Foreground")

dt = Nothing
ds = Nothing

End Sub

'**********************
The resulting file looks like this:

<?xml version="1.0" standalone="yes"?>
<Settings>
<Textbox>
<Foreground>Color [WindowText]</Foreground>
<Font>[Font: Name=Arial, Size=12, Units=3, GdiCharSet=0,
GdiVerticalFont=False]</Font>
</Textbox>
</Settings>
 
J

Jim Hughes

Your sub Read() does not read in the data from the xml file.
(and you are not using dt)

Try this:
//
Private Sub Read()
'Declare objects
Dim ds as Dataset
ds.readXML("C:\path") = ds.tables(0)

txtBox.Font = ds.Tables("Textbox").Rows(0)("Font")
txtBox.ForeColor = ds.Tables("Textbox").Rows(0)("Foreground")

ds = Nothing

End Sub
\\

Noozer said:
To create
\\\
Dim ds as new dataset
dim dt as new datatable
dt.columns.add("TheLastDate",gettype(system.datetime))
dt.rows.add(dt.newrow)
ds.tables.add(dt)
dt.rows(0)("TheLastDate") = date.Now
ds.writeXML("C:\path")
///
To use
\\\
ds.read(XML"C:\path")
dim mydate as datetime = ds.tables(0).rows(0)("TheLastDate")
///

I hope this helps?

Very helpful... It works great!!! I do have one more question though...

It would be great to be able to store object properties so I tried the
code
included below, but it doesn't work. The program complains that the
"Specified cast is not valid". Since the data was written out with a
specific data type, why wouldn't the cast be valid when reading it back
in?
I can break these properties down to simple data types, but I'd rather do
it
this way if it's possible.

'Write settings...
Private Sub Write()

'Declare dataset objects
dim ds as new dataset("Settings")
dim dt as new datatable("Textbox")

'Add columns to the table
dt.columns.add("Foreground", GetType(System.Drawing.Color))
dt.columns.add("Font", gettype(System.Drawing.Font))

'Add a row to the table
dt.Rows.Add(dt.NewRow)

'Add the table to the dataset
ds.Tables.Add(dt)

'Update data in table
dt.Rows(0)("Foreground") = txtBox.Forecolor
dt.Rows(0)("Font") = txtBox.Font

'Write dataset to disk
ds.WriteXML("C:\File.xml")

'Destroy objects
dt = Nothing
ds = Nothing

End Sub

Private Sub Read()
'Declare objects
Dim ds as Dataset
Dim dt as Datatable

txtBox.Font = ds.Tables("Textbox").Rows(0)("Font")
txtBox.ForeColor = ds.Tables("Textbox").Rows(0)("Foreground")

dt = Nothing
ds = Nothing

End Sub

'**********************
The resulting file looks like this:

<?xml version="1.0" standalone="yes"?>
<Settings>
<Textbox>
<Foreground>Color [WindowText]</Foreground>
<Font>[Font: Name=Arial, Size=12, Units=3, GdiCharSet=0,
GdiVerticalFont=False]</Font>
</Textbox>
</Settings>
 
C

Cor Ligthert

Noozer,

You first have to set all the parts of a font appart or to serialize the
font befor you set that to a dataset and for the colours you can in my
opinion use the best the integer which you can get with drawing.color.toargb
http://msdn.microsoft.com/library/d...l/frlrfsystemdrawingcolorclasstoargbtopic.asp

bellow a sample by Tom Shelton for serializing a font.

I hope this helps again?

Cor

\\\Tom Shelton
Private Function SerializeFontObject(ByVal fnt As Font) As String
Dim bf As New BinaryFormatter
Dim mem As New MemoryStream
Try
bf.Serialize(mem, fnt)
Return Convert.ToBase64String(mem.ToArray())
Catch
Return String.Empty
Finally
mem.Close()
End Try
End Function
///
\\\
Private Function DeserializeFontObject(ByVal fnt As String) As Font
Dim bf As New BinaryFormatter
Dim mem As New MemoryStream(Convert.FromBase64String(fnt))
Try
Return DirectCast(bf.Deserialize(mem), Font)
Finally
If Not mem Is Nothing Then
mem.Close()
End If
End Try
End Function
///
 
N

Noozer

I must have miskeyed someplace as I do have the ReadXML in my code. I've
corrected it below.

You have the following line:
ds.readXML("C:\path") = ds.tables(0)
...which doesn't go into my editor. "Expression is a value and therefore
cannot be the targed of an assignment"

....and I still get the Casting error here:
txtBox.Font = ds.Tables("Textbox").Rows(0)("Font")


And as an aside, I just tried to write a dataset to a dataset without luck.
i.e.

dt.columns.add("data", GetType(System.Data.Dataset))
....
dt.rows(0)("data") = ds 'DS contains a verified valid dataset.

....writes ... "<data>System.Data.Dataset</data>"... into the XML file
instead of
...."<data><dsname><dtname><colname>value</colname></dtname></dsname></data>"
....

I think I'm going to need a bit more practice with non-simple data types as
well as finding the limitations of datasets.

Definately helpful stuff though!!!



Jim Hughes said:
Your sub Read() does not read in the data from the xml file.
(and you are not using dt)

Try this:
//
Private Sub Read()
'Declare objects
Dim ds as Dataset
ds.readXML("C:\path") = ds.tables(0)

txtBox.Font = ds.Tables("Textbox").Rows(0)("Font")
txtBox.ForeColor = ds.Tables("Textbox").Rows(0)("Foreground")

ds = Nothing

End Sub
\\

Noozer said:
To create
\\\
Dim ds as new dataset
dim dt as new datatable
dt.columns.add("TheLastDate",gettype(system.datetime))
dt.rows.add(dt.newrow)
ds.tables.add(dt)
dt.rows(0)("TheLastDate") = date.Now
ds.writeXML("C:\path")
///
To use
\\\
ds.read(XML"C:\path")
dim mydate as datetime = ds.tables(0).rows(0)("TheLastDate")
///

I hope this helps?

Very helpful... It works great!!! I do have one more question though...

It would be great to be able to store object properties so I tried the
code
included below, but it doesn't work. The program complains that the
"Specified cast is not valid". Since the data was written out with a
specific data type, why wouldn't the cast be valid when reading it back
in?
I can break these properties down to simple data types, but I'd rather do
it
this way if it's possible.

'Write settings...
Private Sub Write()

'Declare dataset objects
dim ds as new dataset("Settings")
dim dt as new datatable("Textbox")

'Add columns to the table
dt.columns.add("Foreground", GetType(System.Drawing.Color))
dt.columns.add("Font", gettype(System.Drawing.Font))

'Add a row to the table
dt.Rows.Add(dt.NewRow)

'Add the table to the dataset
ds.Tables.Add(dt)

'Update data in table
dt.Rows(0)("Foreground") = txtBox.Forecolor
dt.Rows(0)("Font") = txtBox.Font

'Write dataset to disk
ds.WriteXML("C:\File.xml")

'Destroy objects
dt = Nothing
ds = Nothing

End Sub

Private Sub Read()
'Declare objects
Dim ds as Dataset

ds.ReadXml("C:\File.xml") '***MISSING FROM NEWS POST

txtBox.Font = ds.Tables("Textbox").Rows(0)("Font")
txtBox.ForeColor = ds.Tables("Textbox").Rows(0)("Foreground")

ds = Nothing

End Sub

'**********************
The resulting file looks like this:

<?xml version="1.0" standalone="yes"?>
<Settings>
<Textbox>
<Foreground>Color [WindowText]</Foreground>
<Font>[Font: Name=Arial, Size=12, Units=3, GdiCharSet=0,
GdiVerticalFont=False]</Font>
</Textbox>
</Settings>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top