I have a Windows Service that performs a number of periodic activities, and I want to change the settings of this service from a Windows Forms app. I'm not sure, though, about the best way to make sure the service has the most updated user preferences in it (how often to run, what folders to use for things, whatever else the user can specify). The user can change settings any time, at will, and I'd like the service know about it almost immediately. Here are the options I'm weighing:
I know best is subjective, but I'm interested in any obvious pro or con reasons for these choices. Since I'll have to save my settings between runnings of the application (reboots, etc), I'll have to serialize the settings to disk anyway, so I'm already leaning towards #2 or #3. I'll need a place on disk where I can save the settings, but maybe the AppData folder will work okay, though that will only allow Administrators to change the settings, since they're the only ones that have permission to write to this location (where every user, including the service account, can read it).
Thanks for your insight!
I kinda use your number 2.
But I'm only working in .NET 2 with my application, but it should still apply.
I have a settings class that I use across my 2 programs. Inside this settings class I setup a FileSystemWatcher object that looks at the Settings file.
If the settings file is updated by the other application, my current gets an event trigger to indicate that the settings need to reload.
You can also apply the same principle in your settings screen so that if the (service) other application updates anything during the settings edit, that is reflected in your screen.
I use the AppData (my company/application name directory) to store the file.
The other thing to bear in mind, is that there can be locking on the file while it is being written so you can either use a temp name save, delete old, rename temp method or put some protective locking on the file when reading after the filewatcher event fires that changes have been made.
I use this approach in my FileSystemWatcher before proceeding
IPSDependency.FileSystem.WaitForLockOnFile(Me.mFilePath)
the code for that is like this. (upon reading this now, there may be a better method my using some sleep in here to reduce CPU thrashing)
Public Shared Function IsLockAvailable(ByVal filename As String, ByVal fnfIsOK As Boolean) As Boolean
Dim fi As FileInfo
fi = New FileInfo(filename)
Return IsLockAvailable(New FileInfo(filename), fnfIsOK)
End Function
Public Shared Function IsLockAvailable(ByVal theFile As FileInfo, ByVal fnfIsOK As Boolean) As Boolean
Dim fs As FileStream
Try
If theFile.Exists Then
fs = New FileStream(theFile.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
fs.Close()
Return True
Else
Return fnfIsOK
End If
Catch ex As IOException
'we just let the exception go, because we are only testing the file rather than trying to use it.
Return False
End Try
End Function
Public Shared Sub WaitForLockOnFile(ByVal theFilename As String)
WaitForLockOnFile(New FileInfo(theFilename))
End Sub
Public Shared Sub WaitForLockOnFile(ByVal theFile As FileInfo)
Dim lockAvailable As Boolean
If theFile.Exists Then
While Not lockAvailable
lockAvailable = IsLockAvailable(theFile, False)
End While
End If
End Sub
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With