如何使用 ClickOnce 正确部署带有 sqlite 数据库的 WPF 应用程序

how properly deploy WPF app with sqlite database using ClickOnce

我尝试使用 ClickOnce,但不包括数据库。

当我将数据库 属性 "build action" 更改为内容时,它会在发布文件属性中可见。

https://msdn.microsoft.com/en-us/library/kzy0fky2.aspx

不幸的是,在这种情况下我收到以下错误:

错误 2 生成清单时出现问题。该进程无法访问文件 'H:\Repos\InstalmentsManagement\Installments.Wpf\Database\installments.sqlite',因为它正被另一个进程使用。 Installments.Wpf

我的连接字符串是:

  <connectionStrings>
    <add name="installmentsEntities" connectionString="metadata=res://*/InstallmentsModel.csdl|res://*/InstallmentsModel.ssdl|res://*/InstallmentsModel.msl;provider=System.Data.SQLite.EF6;provider connection string=&quot;data source=|DataDirectory|\Database\installments.sqlite&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

此外,我在启动时做了以下操作以检测数据目录:

    protected override void OnStartup(StartupEventArgs e)
    {
        string executable = System.Reflection.Assembly.GetExecutingAssembly().Location;
        string path = (System.IO.Path.GetDirectoryName(executable));
        AppDomain.CurrentDomain.SetData("DataDirectory", path);

        base.OnStartup(e);      
    }

如果您收到“进程无法访问”本地数据文件,您可能是自己打开了它而不是关闭它。

ClickOnce 将 |DataDirectory| 定义为安装程序数据文件夹。如果您的连接字符串是 |DataDirectory|\Database\installments.sqlite,那么您需要将项目的 Database 文件夹而不是 installments.sqlite 文件标记为数据文件。或者您可以将连接字符串更改为 |DataDirectory|\installments.sqlite

SetData 不“检测”DataDirectory,而是替换它。不要调用 SetData,因为它会替换 ClickOnce 的值。如果你需要知道安装程序的目标数据文件夹,你可以调用 AppDomain.CurrentDomain.GetData("DataDirectory"),但如果你使用 ADO.NET,你甚至不需要这样做; ADO.NET 会将连接字符串中的 |DataDirectory| 替换为安装程序数据文件夹的路径。

您可能只需要删除您的 OnStartup 方法;这就是破坏事物的原因。