Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
356 views
in Technique[技术] by (71.8m points)

c# - Relative path for SQLite not working with WIX Toolset

I'm using SQLite Database and create installer of WPF application with WIX Toolset. The problem is, The below relative path works fine when I directly run from Visual Studio but does not work when I create installer with WIX and after install this installer run program then it gives fatal error for Database file. In Project directory I've made a Database folder, in which the database files reside as you can see in below picture:

enter image description here

After creating installer by WIX Toolset, installed files as below:

enter image description here

inventory_control.db file path: enter image description here

dbConnectionString path:

enter image description here

I've writen code for relative path connection string as under:

Relative Path:

  string relativePath = @"Databaseinventory_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 gives correct current path. The above relative path works fine when I directly run from Visual Studio but does not work when I create installer with WIX. It gives a fatal error. How to resolve?

WIX File:

<?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="Imagesackground.bmp" />
    <WixVariable Id="WixUIDialogBmp" Value="Imagesackground.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="SoftwareInventory 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="SoftwareInventory 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)Databaseinventory_control.db" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

SQLite.Interop.dll: The file SQLite.Interop.dll needed to be installed along with the rest of the runtime files in order for SQLite to function properly.

There are two flavors of the file, x86 and x64 format. It is probably advisable to install both files in their respective folders:

Your installation folder hierarchy - mock-up:

  • YourBinary.exe
  • x86SQLite.Interop.dll
  • x64SQLite.Interop.dll
  • System.Data.SQLite.dll
  • Etc...

Read-Write DB Location: And then your database should be stored in a writeable path (or you need to make the path writeable for regular users using custom ACL permissioning - which is never a great idea).

Exceptions: Obviously try - catch your database connection, update and access code to detect these kinds of issues.


  1. Folder Confusion: Is there a database file inside the Database folder? It sort of looks like the inventory_control.db file is installed to the main application folder, and not that Database sub-folder?

    • Maybe that file has been generated by the application.exe in the wrong folder?
    • Or maybe you have duplicated the file in the main folder for testing purposes?
  2. Hard-Coded Dev-Box Sins?: What does it say in Inventory Control.exe.config?

    • Are there relevant settings in there that could override your code's values?
    • Could there be a hard-coded dev-box sin in there?
  3. Path Builder: I assume you have "message boxed" the paths from the application during launch, in order to ensure that they are correct? I like to copy the path and do a Start => Run and paste the path to see that it opens. Press CTRL + C when the message box shows. Paste into Notepad. Extract the path and try it in Start => Run.

    • string path = currentPath.Substring(0, currentPath.Length - 21);. It is not very robust to hard code the number of characters in the file name to get the parent directory path?
    • Could you improve it by using Path.GetDirectoryName(currentPath)?
    • Or maybe even: string dir = currentPath.Substring(0,currentPath.LastIndexOf('\'));
  4. Attach Debugger & Debug Binaries?: Maybe you could install debug binaries and attach to them for debugging as described here: wix c# app doesn't launch after installing. Just to get a real step-through debugging session.

  5. Path Spaces: That database connection string. Does it need quotes around its path? As in "path with spaces"? You may not have any spaces in the paths for your visual Studio project, but when installed there are spaces in the paths.


This constructs in your source does look weird, why is it necessary?:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...