How do I read the current path of |DataDirectory| from config settings

孤街浪徒 提交于 2019-12-17 13:22:34

问题


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.


回答1:


|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, and will be available if the user roams, or logs on from another machine. This is typically where you want to put editable user 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.




回答2:


The Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) code will return a null value in development every time. The |DataDirectory| is set when the program is installed.

Build the project, then install and test it.

I used that line of code to compact a database in an installed application at runtime.

That code can be set to a variable, as follows... Dim beer as strong

Beer = Environmenr.GetFolderPath(Environment.SpecialFolder.ApplicationData)

This will return the folder path for the INSTALLED |DataDirectory|. Add the database name on with a CStr and another variable...

Dim MyPathA As String = CStr(Beer & "\Workout.mdb")
Dim MyPathB As String = CStr(Beer & "\BackupWorkout.mdb")

Dim JRO As JRO.JetEngine
JRO.CompactDatabase(CStr("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & MyPathA), _
CStr("Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " & MyPathB & ":Jet OLEDB:Engine Type=5"))

On error Errorhandler, 
Errothandler
Kill(MyPathB)

The 1st line is your database, the 2nd line renames it to Backup and compacts it in the same directory. If there is a Backup there, it will trigger the error, which will delete the backup.

After that, say this is button click. Run it all again. Right after the kill line,

Me.Buttonx.PerformClick()

That is how to compact a database in an installed ClickOnce application. Using |DataDirectory| in the code will throw an illegal characters error...



来源:https://stackoverflow.com/questions/12266924/how-do-i-read-the-current-path-of-datadirectory-from-config-settings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!