C# 如何读取 |DataDirectory| 的当前路径 从配置设置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12266924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 22:41:50  来源:igfitidea点击:

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

c#sql-server-cedatadirectory

提问by PAUL DUFRESNE

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 ApplicationDataspecifically 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.

我正在编写一个程序,要求用户在应用程序启动时选择活动数据库。我有一个 Windows 窗体,它将列出存储在ApplicationData子文件夹中的数据库,专门用于存储数据库文件。然而,当我创建一个新数据库时,我需要复制模板数据库,但无法弄清楚它默认存储在哪里。

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 DataDirectoryto 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.

不过,我似乎总是得到一个空值作为回报。有一次我放弃了,并认为我可以将DataDirectory设置为我选择的文件夹,但似乎我在执行我的程序时这样做太晚了,以至于它无法生效。

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.Fillcommand 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.

对于第二部分,我发现我试图在已经执行TableAdapter.Fill命令后修改连接字符串,从而解释了它打开默认数据库的原因。这个谜团已经解开了。然而,第一部分仍然是一个未知数。

Thank You.

谢谢你。

采纳答案by Dour High Arch

|DataDirectory|does not come from config settings; you're mixing up three different things:

|DataDirectory|不是来自配置设置;你混淆了三种不同的东西:

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 AppSettingselement. 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.

这来自配置设置;您必须创建一个 .config 文件并将其放入您的项目中。此特定设置是元素中带有键"DataDirectory"AppSettings元素的值。除非您在 .config 文件中放置一个,否则它不存在。通常这是您放置从未更改的配置或启动数据的地方。您不应将文件路径放在这里,因为它们在用户安装数据库的机器上可能会有所不同。

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:

这是 ADO.NET 连接的连接字符串。ADO.NET 特别对待竖线,它在竖线之间寻找与键名匹配的 AppDomain 数据。您可以通过以下方式获得相同的数据:

AppDomain.CurrentDomain.GetData("DataDirectory")

So what writes the value of DataDirectory? It's done by whatever deploys your executable:

那么 的值写什么DataDirectory?它由任何部署您的可执行文件的人完成:

  • .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.
  • .MSI 安装程序将其定义为应用程序的目标文件夹。
  • ClickOnce 在您的项目中定义了一个特殊的数据文件夹。
  • Web 应用程序使用 App_Data 文件夹。
  • Visual Studio 调试器使用调试文件夹。

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 DataDirectoryfolder for read-only binary data deployed with your executable.

请注意,.MSI 安装程序可以允许用户更改数据目录;这就是为什么您永远不应该硬编码或更改的原因DataDirectory,如果您这样做,将无法找到您的应用程序数据的部署位置。您通常将该DataDirectory文件夹用于与可执行文件一起部署的只读二进制数据。

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 DataDirectorynot 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 DataDirectorygets reinstalled or deleted. Users don't like it when you delete their data, so don't save it to DataDirectory.

如果您需要写入与您的可执行文件一起部署的数据,您应该首先将它复制到您知道用户可以写入的地方,例如 to Environment.SpecialFolder.ApplicationData,然后写入副本。不仅DataDirectory不一定是用户可写的,它是部署的一部分而不是用户数据的一部分;如果您修复或卸载可执行文件,则会DataDirectory重新安装或删除。当您删除他们的数据时,用户不喜欢它,所以不要将其保存到DataDirectory.

回答by Dave Brown

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.

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)代码将在发展的每一次返回空值。|数据目录| 安装程序时设置。

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...

这将返回 INSTALLED |DataDirectory| 的文件夹路径。使用 CStr 和另一个变量添加数据库名称...

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.

第一行是您的数据库,第二行将其重命名为 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...

这就是在已安装的 ClickOnce 应用程序中压缩数据库的方法。使用 |数据目录| 在代码中会抛出非法字符错误...

回答by Demilitarized Zone

Put this line before using the ConnectionString, TableAdapter, etc... to create the thing so called DataDirectory.

将此行放在使用 ConnectionString、TableAdapter 等之前...以创建所谓的DataDirectory

I have just tested successfully by putting it right before TableAdapter.Fill(DataSet.DataTable);

我刚刚通过将它放在 TableAdapter.Fill(DataSet.DataTable); 之前成功地进行了测试。

AppDomain.CurrentDomain.SetData("DataDirectory", @"Full path to your data folder");

I cannot find where and what the DataDirectoryis, because it doesn't exist so MSSQL will take the BaseDirectoryof AppDomain.CurrentDomain instead.

我找不到DataDirectory 的位置和内容,因为它不存在,因此 MSSQL 将采用AppDomain.CurrentDomain的BaseDirectory