SQLite的相对路径不适用于WIX Toolset

时间:2018-09-13 18:11:56

标签: c# wpf sqlite wix

我正在使用SQLite数据库,并使用WIX Toolset创建WPF应用程序的安装程序。问题是,当我直接从Visual Studio中运行时,下面的相对路径可以正常工作,但是当我使用WIX创建安装程序并在安装此安装程序运行程序后,则它无法正常工作,那么它给数据库文件提供致命错误。 在Project目录中,我创建了一个Database文件夹,数据库文件位于其中,如下图所示:

enter image description here

通过WIX Toolset创建安装程序后,已安装文件如下:

enter image description here

inventory_control.db文件路径: enter image description here

dbConnectionString路径:

enter image description here

我已经为相对路径连接字符串编写了如下代码:

相对路径:

  string relativePath = @"Database\inventory_control.db";
        string currentPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
        //string path = currentPath.Substring(0, currentPath.Length - 21);
        string path = Path.GetDirectoryName(currentPath);
        string absolutePath = System.IO.Path.Combine(path, relativePath);
        string dbConnectionString = string.Format("Data Source={0};Version=3;Pooling=True;Max Pool Size=100;", absolutePath);

        //string dbConnectionString = "Data Source=inventory_control.db";
        sQLiteConnection = new SQLiteConnection(dbConnectionString);

dbConnectionString给出正确的电流路径。 当我直接从Visual Studio运行时,上述相对路径可以正常工作,但是当我使用WIX创建安装程序时,上述相对路径不起作用。它给出了致命错误。如何解决?

WIX文件:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"><?define Inventory Control_TargetDir=$(var.Inventory Control.TargetDir)?>
    <Product Id="f941ba49-4369-44d4-aa0c-b77f20aa41db" Name="Inventory Control" Language="1033" Version="1.0.0.0" Manufacturer="devtros.com" UpgradeCode="ce092371-53cc-4be9-ab5d-c7a2685af970">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <Icon Id="app_icon.ico" SourceFile="$(var.ProjectDir)app_icon.ico" />
    <Property Id="ARPPRODUCTION" Value="app_icon.ico" />

    <WixVariable Id="WixUIBannerBmp" Value="Images\background.bmp" />
    <WixVariable Id="WixUIDialogBmp" Value="Images\background.bmp" />
    <WixVariable Id="WixUILicenseRtf" Value="$(var.ProjectDir)License.rtf" />

    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
    <UIRef Id="WixUI_InstallDir" />

        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <MediaTemplate EmbedCab="yes" />

        <Feature Id="ProductFeature" Title="Inventory Control" Level="1">
            <ComponentGroupRef Id="ProductComponents" />
      <ComponentRef Id="ApplicationShortcut" />
      <ComponentRef Id="ApplicationShortcutDesktop" />
            <ComponentGroupRef Id="Database_files" />
        </Feature>
    </Product>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="Inventory Control">
          <Directory Id="Files" Name="Files" />
          <Directory Id="Database" Name="Database" />
        </Directory>
            </Directory>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="ApplicationProgramsFolder" Name="Inventory Control" />
      </Directory>
      <Directory Id="DesktopFolder" Name="Desktop" />
        </Directory>
    </Fragment>

  <Fragment>
    <DirectoryRef Id="ApplicationProgramsFolder">
      <Component Id="ApplicationShortcut" Guid="9bd13330-6540-406f-a3a8-d7f7c69ae7f9">
        <Shortcut Id="ApplicationStartMenuShortcut" Name="Inventory Control" Description="Inventory Control" Target="[INSTALLFOLDER]Inventory Control.exe" WorkingDirectory="INSTALLFOLDER" />
        <RemoveFolder Id="RemoveApplicationProgramsFolder" Directory="ApplicationProgramsFolder" On="uninstall" />
        <RegistryValue Root="HKCU" Key="Software\Inventory Control" Name="installed" Type="integer" Value="1" KeyPath="yes" />
      </Component>
    </DirectoryRef>
    <DirectoryRef Id="DesktopFolder">
      <Component Id="ApplicationShortcutDesktop" Guid="cde1e030-eb64-49a5-b7b8-400b379c2d1a">
        <Shortcut Id="ApplicationDesktopShortcut" Name="Inventory Control" Description="Inventory Control" Target="[INSTALLFOLDER]Inventory Control.exe" WorkingDirectory="INSTALLFOLDER" />
        <RemoveFolder Id="RemoveDesktopFolder" Directory="DesktopFolder" On="uninstall" />
        <RegistryValue Root="HKCU" Key="Software\Inventory Control" Name="installed" Type="integer" Value="1" KeyPath="yes" />
      </Component>
    </DirectoryRef>
  </Fragment>

    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
            <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
            <!-- <Component Id="ProductComponent"> -->
                <!-- TODO: Insert files, registry keys, and other resources here. -->
            <!-- </Component> -->
            <Component Id="Inventory_Control.exe" Guid="0a7e7061-201b-4d49-adeb-4449e9c4da3e">
              <File Id="Inventory_Control.exe" Name="Inventory Control.exe" Source="$(var.Inventory Control_TargetDir)Inventory Control.exe" />
            </Component>
            <Component Id="Inventory_Control.exe.config" Guid="28323615-8159-4116-b1ac-e29a70bf2593">
              <File Id="Inventory_Control.exe.config" Name="Inventory Control.exe.config" Source="$(var.Inventory Control_TargetDir)Inventory Control.exe.config" />
            </Component>
            <Component Id="System.Windows.Controls.Input.Toolkit.dll" Guid="7d678201-767a-416b-b645-b2cb7d514893">
              <File Id="System.Windows.Controls.Input.Toolkit.dll" Name="System.Windows.Controls.Input.Toolkit.dll" Source="$(var.Inventory Control_TargetDir)System.Windows.Controls.Input.Toolkit.dll" />
            </Component>
            <Component Id="System.Data.SQLite.dll" Guid="178a5aef-c027-4215-81ae-f148ab6cd472">
              <File Id="System.Data.SQLite.dll" Name="System.Data.SQLite.dll" Source="$(var.Inventory Control_TargetDir)System.Data.SQLite.dll" />
            </Component>
            <Component Id="Zen.Barcode.Core.dll" Guid="20e34fc3-0066-4ffd-b401-518bc1177098">
              <File Id="Zen.Barcode.Core.dll" Name="Zen.Barcode.Core.dll" Source="$(var.Inventory Control_TargetDir)Zen.Barcode.Core.dll" />
            </Component>
            <Component Id="WPFToolkit.dll" Guid="8d974e65-defb-4675-b9e0-ff617e5ab1da">
              <File Id="WPFToolkit.dll" Name="WPFToolkit.dll" Source="$(var.Inventory Control_TargetDir)WPFToolkit.dll" />
            </Component>
        </ComponentGroup>
    </Fragment>

  <Fragment>
    <ComponentGroup Id="Database_files" Directory="Database">
      <Component Id="Database_inventory_control.db" Guid="0104b919-0aa9-4dc5-9492-14c474d97cf1">
        <File Id="Database_inventory_control.db" Name="inventory_control.db" Source="$(var.Inventory Control_TargetDir)Database\inventory_control.db" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

1 个答案:

答案 0 :(得分:0)

  

SQLite.Interop.dll :为了安装SQLite,需要将文件SQLite.Interop.dll与其他运行时文件一起安装   正常运行。

     

文件有两种样式,x86x64格式。它是   最好将两个文件都安装在各自的文件夹中:

     

您的安装文件夹层次结构-模型:

     
      
  • YourBinary.exe
  •   
  • x86\SQLite.Interop.dll
  •   
  • x64\SQLite.Interop.dll
  •   
  • System.Data.SQLite.dll
  •   
  • Etc...
  •   
     

读写数据库位置 :然后,您的数据库应存储在可写路径中(或者您需要使用自定义ACL权限使常规用户可写该路径-这绝不是一个好主意。

     

例外 :显然try - catch您的数据库连接,更新和访问代码可检测到此类问题。


  1. 文件夹混乱 :“数据库”文件夹中是否有数据库文件?看起来 inventory_control.db 文件已安装到主应用程序文件夹中,而不是 Database 子文件夹中?

    • 也许该文件是由application.exe在错误的文件夹中生成的?
    • 或者您可能出于测试目的已经复制了主文件夹中的文件?
  2. 硬编码Dev-Box罪孽? :在 Inventory Control.exe.config 中怎么说?

    • 其中是否存在可以覆盖代码值的相关设置?
    • 里面可能有硬编码的开发箱罪吗?
  3. 路径生成器 :我假设您在启动过程中将应用程序的路径“装箱”,以确保路径正确?我喜欢复制路径并执行Start => Run并粘贴路径以查看路径是否打开。显示消息框时,按CTRL + C。粘贴到记事本中。提取路径,然后在Start => Run中尝试。

    • string path = currentPath.Substring(0, currentPath.Length - 21);。硬编码文件名中的字符数以获得父目录路径不是很可靠吗?
    • 您可以使用Path.GetDirectoryName(currentPath)进行改进吗?
    • 或者甚至:string dir = currentPath.Substring(0,currentPath.LastIndexOf('\\'));
  4. 附加调试器和调试二进制文件吗? :也许您可以按照以下说明安装调试二进制文件并附加到它们进行调试:wix c# app doesn't launch after installing。只是为了获得真正的逐步调试会话。

  5. 路径空间 :该数据库连接字符串。它的路径是否需要引号?如“空间路径”?您的Visual Studio项目的路径中可能没有空格,但是在安装时,路径中有空格。


您的源代码中的这个结构看起来很奇怪,为什么有必要?

  • <?define Inventory Control_TargetDir=$(var.Inventory Control.TargetDir)?>