【问题标题】:Visual studio app.config file database path for installed apps已安装应用程序的 Visual Studio app.config 文件数据库路径
【发布时间】:2021-10-01 01:57:49
【问题描述】:

我在我的应用程序中使用本地数据库,当我生成安装文件(由Installer Package)时,安装程​​序后会出现数据库路径错误。

示例

an attempt to attach an auto-named database for file....
//OR
The given path format is not supported

我尝试在app.config 文件中编辑数据库路径,但每次都失败,默认情况下我的代码行是这样的:

<add name="SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"
            connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\SampleDatabase.mdf;Integrated Security=True"
            providerName="System.Data.SqlClient" />

我的应用程序安装在C:\Program Files (86)\App_Folder\Setup 请注意,未来的用户可能会在自定义路径中安装它,所以我需要一种方法来获取已安装应用程序的动态路径

我的问题是我怎样才能得到应用安装路径来替换这部分AttachDbFilename=|DataDirectory|\SampleDatabase.mdf

【问题讨论】:

    标签: c# visual-studio winforms windows-installer


    【解决方案1】:

    您可以尝试使用AppDomain.CurrentDomain.SetData 方法来更改您的 mdf 文件路径。

    既然,我不知道你是怎么发布winform项目的。

    我建议你使用 Clickonce 来发布它。

    首先,请将您的 mdf 文件包含在您的项目中。

    其次,你可以试试下面的代码,在你发布后更改安装路径。

     private void Form1_Load(object sender, EventArgs e)
                {
                    if(System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                    {
                        string path = ApplicationDeployment.CurrentDeployment.DataDirectory; //Get installed path
                        AppDomain.CurrentDomain.SetData("DataDirectory", path);//set the DataDirectory 
                    }
                }
    

    最后,根据我的测试,我可以从 mdf 文件中获取信息,然后将它发布并安装到另一台计算机上。

    【讨论】:

    • 您好,感谢您的回答(特别包括图片)。关于Form1_Load() 放在Program.cs 文件static void Main() 函数里不是更好吗?因为我的应用程序首先打开登录表单,然后打开 form1(PS:登录表单将在成功登录时关闭)这就是为什么我说如果我把它放在 main() 函数中。你有什么建议?
    • 哦,目前我的数据库文件不在任何文件夹中(截图)ibb.co/f2NMbKq 可以吗?还是我必须把它放在文件夹里?
    • @mafortis,如果您想在发布后直接访问应用程序中的文件,您可以尝试代码“ApplicationDeployment.CurrentDeployment.DataDirectory;”。另外,我在答案中更改了代码。
    • 我正在使用包安装程序(Visual Studio 扩展)来创建安装文件。我还应该在我的设置文件中手动添加 db 文件还是自动包含它?
    • @mafortis,根据我的研究,您需要手动在安装文件中添加 db 文件。您可以参考链接Include folder in setup project
    【解决方案2】:

    在生产模式下|DataDirectory| 指的是“bin”目录,而不是“app_data”。如果你把.mdf文件放在app_data目录下,可以这样改:

    |DataDirectory|\SampleDatabase.mdf|DataDirectory|\app_data\SampleDatabase.mdf

    <add name="SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"
            connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\app_data\SampleDatabase.mdf;Integrated Security=True"
            providerName="System.Data.SqlClient" />
    

    更新1:

    我正在发送一些代码。我只是想给你一个想法。您可以根据自己的情况进行更改。

    private void Form1_Load(object sender, EventArgs e)
    {
        if (!IsExist())
        {
            CreateDatabase();
            CreateTables();
        }
    }
    
    // Create the Database
    private void CreateDatabase()
    {
        string basePath = Environment.CurrentDirectory;
        string mdfFile = "TestDatabase.mdf";
        string ldfFile = "TestDatabase_Log.mdf";
        string mdfFullPath = System.IO.Path.Combine(basePath, "Data", mdfFile);
        string ldfFullPath = System.IO.Path.Combine(basePath, "Data", ldfFile);
    
        SqlConnection myConn = new SqlConnection("Server=.;Data Source=(LocalDB)\\MSSQLLocalDB;Integrated security=SSPI;database=master");
        string str = "CREATE DATABASE TestDatabase ON PRIMARY " +
                "(NAME = TestDatabase, " +
                $"FILENAME = '{mdfFullPath}', " +
                "SIZE = 2MB, MAXSIZE = 10MB, FILEGROWTH = 10%)" +
                "LOG ON (NAME = MyDatabase_Log, " +
                $"FILENAME = '{ldfFullPath}', " +
                "SIZE = 1MB, " +
                "MAXSIZE = 5MB, " +
                "FILEGROWTH = 10%)";
    
    
        SqlCommand myCommand = new SqlCommand(str, myConn);
        try
        {
            myConn.Open();
            myCommand.ExecuteNonQuery();
            MessageBox.Show("DataBase is Created Successfully", "MyProgram", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        catch (System.Exception ex)
        {
            MessageBox.Show(ex.ToString(), "MyProgram", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        finally
        {
            if (myConn.State == ConnectionState.Open)
            {
                myConn.Close();
            }
        }
    }
    
    // Create the tables and other stuff that you want
    private void CreateTables()
    {
        string conStr = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data\TestDatabase.mdf;Integrated Security=True;Connect Timeout=30";
    
        SqlConnection myConn = new SqlConnection(conStr);
        string str = @"CREATE TABLE [dbo].[TestTable]
                        (
                            [Id] INT NOT NULL PRIMARY KEY, 
                            [Test] NVARCHAR(50) NULL
                        )";
    
        SqlCommand myCommand = new SqlCommand(str, myConn);
        try
        {
            myConn.Open();
            myCommand.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString(), "MyProgram", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        finally
        {
            if (myConn.State == ConnectionState.Open)
            {
                myConn.Close();
            }
        }
    }
    
    // Check if there is the database
    private bool IsExist()
    {
        string basePath = Environment.CurrentDirectory;
        string mdfFile = "TestDatabase.mdf";
        string mdfFullPath = System.IO.Path.Combine(basePath, "Data", mdfFile);
    
        return System.IO.File.Exists(mdfFullPath);
    }
    

    【讨论】:

    • 感谢您的回答,我有同样的问题要问您,就像我问杰克一样,我必须将我的 mdf 文件复制到我的安装程序吗?我是否应该在复制该 mdf 文件之前对其进行任何更改(如果需要复制)? TBH 这是我的第一次尝试,我绝对是新手,所以我需要一步一步的指导才能让它发挥作用(正如我在赏金描述中解释的那样)。谢谢
    • 没关系。如果它不存在,您可以复制它或在第一次运行时制作它。你不需要改变任何东西。我认为问题出在path,而不是文件格式或其他任何问题。
    • 假设我不复制我的数据库文件,你能指导我如何在第一次运行时生成一个吗?也许这解决了我的问题
    • 你使用的是Microsoft SQL Server Database file数据源吗?
    • 我想是的(我不知道你提到的它的长名称)但它创建的文件是.mdf 格式并且它是离线的(本地)。我没有为此使用任何在线数据库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多