I'm writing a program that requires the user to select the active database at application startup. I have a Windows Form that will list the databases stored in a sub-folder of ApplicationData specifically for storing the database files. When I create a new database, however, I need to copy the the template database, but can't figure out where it's stored by default.
I've tried:
dpath = ConfigurationManager.AppSettings["DataDirectory"];
I always seem to get a null value in return though. At one point I gave up and figured I could just set the DataDirectory to a folder of my choice, but it seems I'm doing this too late in the execution of my program for it to take effect.
newdpath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\MyAppFolder";
I would appreciate any suggestions on how to either find the location of the database, or set it myself early enough to affect the program operation.
EDIT:
For the second part, I've discovered that I was trying to modify the connection string after a TableAdapter.Fill command had already been performed, thus explaining why it was opening the default database. That mystery has been solved. The first part, however is still a an unknown.
Thank You.
|DataDirectory|
does not come from config settings; you're mixing up three different things:
ConfigurationManager.AppSettings["DataDirectory"]
This comes from config settings; a .config file you have to create and put into your project. This particular setting is the value of the element with key "DataDirectory"
in the AppSettings
element. This doesn't exist unless you put one in the .config file. Typically this is where you put configuration or startup data that is never changed. You should not put file paths here, as they can be different on the machine users install your database to.
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
This is the path to the current user's roaming application data folder defined by the operating system your app was installed on. You cannot change this, it is defined by the OS. You can be sure this folder is writable by the user, will not be deleted if the user uninstalls your application, and will be available if the user roams or logs on from another machine. This is typically where you want to put editable application data.
SqlConnection("Data Source=|DataDirectory|DatabaseFileName.sdf;...")
This is a connection string for an ADO.NET connection. ADO.NET treats vertical bars specially, it looks for an AppDomain data matching the key name between the vertical bars. You can get the same data with:
AppDomain.CurrentDomain.GetData("DataDirectory")
So what writes the value of DataDirectory
? It's done by whatever deploys your executable:
Note that .MSI installers can allow the user to change the DataDirectory; this is why you should never hard-code or change DataDirectory
, if you do that there is no way to find where your application data was deployed. You typically use the DataDirectory
folder for read-only binary data deployed with your executable.
If you need to write to the data deployed with your executable you should first copy it someplace you know the user will be able to write to, such as to Environment.SpecialFolder.ApplicationData
, and write to the copy. Not only is DataDirectory
not necessarily writable by users, it is part of the deployment and not part of the user data; if you repair or uninstall your executable then DataDirectory
gets reinstalled or deleted. Users don't like it when you delete their data, so don't save it to DataDirectory
.