|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:
- .MSI installers define it as the app's target folder.
- ClickOnce defines a special data folder in your project.
- Web apps use the App_Data folder.
- The Visual Studio debugger uses the debug folder.
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
.