Относительный путь для sqlite, не работающего с wix toolset

Я использую базу данных SQLite и создаю установщик приложения WPF с WIX Toolset. Проблема в том, что приведенный ниже относительный путь отлично работает, когда я напрямую запускаю из Visual Studio, но не работает, когда я создаю установщик с WIX, и после установки этой программы запуска установщика он дает фатальную ошибку для файла базы данных. В каталоге проекта я создал папку базы данных, в которой находятся файлы базы данных, как вы можете видеть на рисунке ниже:

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>
2
0
444
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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
  • x86\SQLite.Interop.dll
  • x64\SQLite.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. Путаница с папками: Есть ли файл базы данных в папке базы данных? Похоже, что в основную папку приложения устанавливается файл inventory_control.db, а не подпапка База данных?

    • Может быть, этот файл был создан application.exe не в той папке?
    • Или, может быть, вы продублировали файл в основной папке для тестирования?
  2. Жестко запрограммированные грехи Dev-Box?: Что написано в Inventory Control.exe.config?

    • Есть ли там соответствующие настройки, которые могут переопределить значения вашего кода?
    • Может ли там быть жестко запрограммированный грех dev-box?
  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# не запускается после установки. Просто чтобы получить настоящий пошаговый сеанс отладки.

  5. Пространства пути: Эта строка подключения к базе данных. Нужны ли ему цитаты вокруг своего пути? Как в «дорожке с пробелами»? У вас может не быть пробелов в путях для вашего проекта Visual Studio, но при установке в путях есть пробелы.


Эта конструкция в вашем исходнике выглядит странно, зачем она нужна ?:

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

Благодарю. у меня есть жесткий путь кода только для целей тестирования, но он не работает. Этот путь открылся нормально при запуске> отлично работает ............. но снова программа получает фатальную ошибку ...... string dircPath = "C: \\ Program Files (x86) \\ inventory control \\ База данных \\ inventory_control.db "; sQLiteConnection = новый SQLiteConnection (dircPath);

zohaib 14.09.2018 07:34

Я также прикрепил отладчик, он дает соединение NULL Sqlite

zohaib 14.09.2018 07:57

пожалуйста, посмотрите мой обновленный вопрос. я прикрепил изображения пути и файла db

zohaib 14.09.2018 08:02

Вы устанавливаете на тот же ящик, что и разрабатываете? Каковы требования к зависимости от среды выполнения для SQLite? Разве это не просто dll? Это sqlite3.dll? Попробуйте найти его, сбросить в целевую папку и протестировать.

Stein Åsmul 14.09.2018 14:30

@zohaib Что делать, если файл базы данных доступен только для чтения для выполняющего пользователя? В зависимости от места установки, которое обычно имеет место. Насколько я могу судить, это может выглядеть так, как будто все работает нормально, пока вы не попытаетесь записать в базу данных. Тогда вы получите исключение.

Stein Åsmul 14.09.2018 16:03

@zohaib Похоже, что файл SQLite.Interop.dll может понадобиться в подпапке x64 или x86 вне места установки основного исполняемого файла.

Stein Åsmul 14.09.2018 16:06

Проблема заключалась в выпуске только для чтения? Если это так, я обновлю свой ответ, чтобы отразить это, чтобы другие могли сэкономить время и не читать все.

Stein Åsmul 14.09.2018 16:20

вы можете опубликовать свой ответ. была проблема в x64 и x86. Папка не может быть создана, поэтому возникла фатальная ошибка

zohaib 14.09.2018 16:24

Я сделал сводный раздел для своего ответа выше.

Stein Åsmul 14.09.2018 16:32

Асмуль, пожалуйста, помогите и по этому вопросу stackoverflow.com/questions/52334847/…

zohaib 14.09.2018 17:17

Я начал отвечать, но вы удалили вопрос, так что я полагаю, что вы его отсортировали. Это база данных для каждого пользователя или общая для всех пользователей коробки?

Stein Åsmul 14.09.2018 19:28

да, я удалил, потому что нашел решение. кстати, большое спасибо

zohaib 14.09.2018 20:49

эта база данных для каждого пользователя

zohaib 14.09.2018 20:49

Вы в корпоративной среде? Или вы делаете пакет для общего распространения? Если вы устанавливаете базу данных для каждого пользователя, то другие пользователи, выполняющие вход на ПК, обычно не смогут запустить приложение. Затем следует установить настройку «для каждого пользователя», чтобы ярлык для запуска приложения не был виден другим пользователям. Я думаю, вы можете заменить InstallScope="perMachine" на InstallScope="perUser", чтобы добиться этого. Настройки для отдельных пользователей немного сложнее управлять и удалять, поскольку они доступны не для всех учетных записей пользователей.

Stein Åsmul 14.09.2018 21:10

Другие вопросы по теме