0

I am working on a VB.NET / WPF application which will use SQL Compact Edition databases.

The application should allow the user to save and load different versions of the database.

To do this, my intention was to have a standard database name (e.g. myDatabase.sdf) which would be saved in the DataDirectory.

Then the user would have an option to save a version of the current data (calling it what they want e.g. savedDatabase1.sdf) and the application would then take a copy of the database from DataDirectory and save it to another location (e.g. a SavedDatabase folder created in the Windows app data area) and to load a different version of the database, the application could copy the database from the SavedDatabase folder and overwrite the database in the DataDirectory location.

I can see solutions for overriding the data directory location, but I can't find any code which allows you to retrieve the path of the current data directory folder so it can be used in any file copy activities as described above.

So my question is - How do I programmatically retrieve the full path currently being used as the data directory?

Rooq
  • 81
  • 1
  • 9
  • Do you mean you want to get the application execution folder? – Mederic May 02 '17 at 12:30
  • I don't think it is necessarily the application execution folder? So, I am using |DataDirectory| in the connection string, which when running in VS, it creates a copy of the database in the Debug folder. I can't remember where it creates it when I publish the app and run it that way. I need to ensure that the path I retrieve is exactly where the database is being created when the application is deployed – Rooq May 02 '17 at 12:31
  • "standard database name which would be saved in the DataDirectory." means this directory should be known to system already or it can come from a config/db table? I did not understand the question. – Anil May 02 '17 at 12:31
  • Ok, I will amend the question when I get home from work and can copy and paste in some real code. Lets say for now, my database is called myDatabase.sdf and this is saved in DataDirectory. I want to be able to make a copy of this database and save to another location. I also want to be able to overwrite this database from a previously saved copy. – Rooq May 02 '17 at 12:36
  • why don't u just use: `System.AppDomain.CurrentDomain.BaseDirectory` to get base directory and then create a directory there called: `DataDirectory`? – Mederic May 02 '17 at 12:40
  • I'll have a look at that. Is this location likely to be always Read/Write rather than Read-only? – Rooq May 02 '17 at 12:43
  • i think you should save the db in the local appdata, see the answer to this [question](http://stackoverflow.com/questions/867485/c-sharp-getting-the-path-of-appdata) –  May 02 '17 at 12:52
  • is it possible to reference the connection string in app.config to point to this? as I will currently have something like connectionString="Data source=|DataDirectory|myDatabase.sdf;" – Rooq May 02 '17 at 13:02
  • You can retrieve the "DataDirectory" of a Click-Once published application using `AppDomain.CurrentDomain.GetData("DataDirectory")`. You can look at the [System.Data.Common.DbConnectionOptions.ExpandDataDirectory method](http://referencesource.microsoft.com/#System.Data/System/Data/Common/DbConnectionOptions.cs,266554ab1b1bbe1c,references) to see how "DataDirectory" is replaced in the connection string. – TnTinMn May 05 '17 at 04:22

1 Answers1

0

You could save all the data in the same folder as the application:

System.AppDomain.CurrentDomain.BaseDirectory

However if you are not sure you have access to that folder you can always write to the Application Data which is made for this:

Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)

Then in this location you can create your own application directory and then your sub directories.

simple example would be:

Dim DataPath as String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) & "/MyApplication/Data/"
connectionString="Data source=|" & DataPath &"myDatabase.sdf;"
Mederic
  • 1,949
  • 4
  • 19
  • 36
  • Using Environment.SpecialFolder.LocalApplicationData would be a workaround. My only concern would be that I would not be able to specify the connection string just once in the app.config file and would need to construct this in each .vb file which needs to access the database. Although, thinking about it I could possibly use a public class to return the connection string each time which would be relatively painless – Rooq May 02 '17 at 13:27
  • just create in your app config the path with a special string like: @@@APPDATA@@@ and then replace this dynamically with : `Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData` – Mederic May 02 '17 at 13:35
  • Or on the app first launch just replace the app.config with the correct connection string. – Mederic May 02 '17 at 13:37
  • This looks promising. I'll hopefully test it tonight...thanks. – Rooq May 02 '17 at 13:41
  • No problem if any questions feel free to ask and if the answer helped you and is working tonight then you can accept the answer. – Mederic May 02 '17 at 13:47
  • Sorry, another newbish question. My databases are automatically copied to the output folder which is what |DataDirectory| would resolve to (i have copy if newer set against the database file property). However, if I am changing the location to the LocalApplicationData path, how do I instead force the initial copy to this path? – Rooq May 03 '17 at 20:26
  • I have made some progress (i think). By changing the Publish options to amend the database in the Application files to "Include" instead of "Data", it is saving the database in the base directory, instead of a data folder for which I could not resolve a path. this gives me an actual location i can copy the file from. I'll have another play with it tomorrow to see if I can now do everything i need to. – Rooq May 03 '17 at 21:14
  • 1
    Yes, managed to do what I needed to. Although I havent exactly implemented your solution, I have marked as the correct answer as it has pointed me in the right direction. thanks! – Rooq May 04 '17 at 20:05