Использование любого процессора из нескольких файлов (x64 / x86) - PullRequest
0 голосов
/ 09 сентября 2018

Пояснение: Я использую C-Sharp на VS2017 для нацеливания файла Sqlite3 на 64-битной машине Win10. Использование фреймворка составляет 4,5 , так как миграция с Win7 поэтому понятна Клиент не хочет разделить версии выпуска, поэтому продукт должен поддерживать «любой процессор».

Ошибка ref: «Не удалось загрузить файл или сборку» System.Data.SQLite.dll 'или одну из ее зависимостей. «

Целевая платформа: Любой процессор

Причина ошибки (в этом сценарии): Файл DLL предназначен для систем x64, тогда как я вынужден продолжать использовать опцию «Любой процессор».

Кроме того: Я скачал оба файла DLL SQLite из http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki. Оттуда я также восстановил точные исходные файлы для SQLite3. Однако интеграция привела к тому, что моя строка «using» не «видела» папку Filehandler, которая содержала источник SQLite.

Этот является повторным вопросом, я видел решения, начиная от пакетов NuGet и заканчивая несколькими ответами, ссылающимися на строки «myapp.exe / x86 / sqlite3.data.dll» и «myapp». exe / x64 / sqlite3.data.dll 'без указания местоположения файла приложения, в которое нужно вставить эти строки. Оставьте одного, чтобы задаться вопросом, как они тогда могли бы ссылаться в файлах классов.
Динамические результаты показывают, что с помощью DLLImport вы можете перестраивать методы (например, MYSQLConnector) в качестве метода. Хотя тогда я подозреваю много повторений в классе, некоторые требования на стороне клиента при загрузке проекта, такие как чтение версии Windows.

повтор ! повтор ! повтор !

Клиент не хочет использовать пакеты NuGet. Поскольку этот проект не должен включать стороннюю обработку ссылок.

Как мне решить эту проблему? Так что моя форма, используя методы:

SQLiteConnection (ConnectionString)

и

SQLiteDataReader

Может использоваться с опцией «Любой процессор».

Обновление

Это базовый код для выполнения, в результате которого возникает ошибка, связанная с приоритетом «Любой ЦП».

void doWork(string path) {
            string valueFound = "";
            if (!System.IO.File.Exists(path)) throw new System.IO.FileNotFoundException("Cant find file", path);

            var connectionString = "Data Source=" + path + ";pooling=false";
            using (var conn = new SQLiteConnection(connectionString))
            {
                using (var cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "SELECT value FROM values WHERE value = ''";
                    conn.Open();
                    using (SQLiteDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            valueFound = (String)reader["value1"];
                        });
                    }
                }
            }
            MessageBox.Show("We have a value: " + valueFound);
        } 

1 Ответ

0 голосов
/ 09 сентября 2018

Вы можете использовать функцию предварительной загрузки собственной библиотеки, как описано на веб-сайте System.Data.SQLite :

Если машины разработчика и заказчика могут иметь разные процессоры В архитектурах может потребоваться более одного двоичного пакета. За это Ситуация, использующая встроенную функцию предварительной загрузки библиотеки рекомендуемые. Он доступен с версии 1.0.80.0 и включен дефолт. Чтобы воспользоваться этой функцией, отдельная управляемые и взаимодействующие сборки должны использоваться при развертывании XCOPY (то есть эта функция не поддерживается сборкой смешанного режима, ни когда сборка развернута в глобальном кэше сборок), в результате чего в развертывании приложения, которое выглядит примерно так:

  • <bin>\App.exe (необязательно, исполняемая сборка приложения только для управления)
  • <bin>\App.dll (необязательно, сборка библиотеки приложений только для управления)
  • <bin>\System.Data.SQLite.dll (обязательно, сборка активной зоны только для управления)
  • <bin>\System.Data.SQLite.Linq.dll (необязательно, сборка LINQ только для управления)
  • <bin>\System.Data.SQLite.EF6.dll (опция, сборка EF6 только для управления)
  • <bin>\x86\SQLite.Interop.dll (требуется, сборка внутреннего взаимодействия x86)
  • <bin>\x64\SQLite.Interop.dll (обязательно, x64 встроенная сборка взаимодействия)

Строка "<bin>" выше представляет каталог, в котором двоичные файлы приложения должны быть развернуты на целевом компьютере. С встроенная функция предварительной загрузки библиотеки и приложение Развертывание показано выше, сборка System.Data.SQLite только для управления будет пытаться автоматически определить архитектуру процессора текущий процесс и предварительно загрузите соответствующую нативную библиотеку.


Пошаговая инструкция по использованию функции предварительной загрузки без пакета Nuget.

  1. Удалите все копии всех System.Data.SQLite.dll, которые есть в вашем проекте, и убедитесь, что в вашей системе не зарегистрировано System.Data.SQLite.dll в глобальном кэше сборок.

  2. В папке «Проект» добавьте подпапку с именами «x64» и подпапку с именем «x86».

  3. Чтобы использовать это, вы должны загрузить два архива ZIP с веб-сайта System.Data.SQLite.

  4. Загрузите второй ZIP-файл, указанный в разделе «Предварительно скомпилированные двоичные файлы для 64-битной Windows (.NET Framework 4.5)», в котором он НЕ говорит «смешанный режим». В настоящее время это http://system.data.sqlite.org/downloads/1.0.109.0/sqlite-netFx45-binary-x64-2012-1.0.109.0.zip

Скопируйте файл System.Data.SQLite.dll из этого zip-файла в папку вашего проекта. Скопируйте файл SQLite.Interop.dll из этого zip-файла в папку x64 ниже папки вашего проекта.

  1. Загрузите второй ZIP-файл, указанный в разделе «Предварительно скомпилированные двоичные файлы для 32-битной Windows (.NET Framework 4.5)», в котором он НЕ говорит «смешанный режим». В настоящее время. это http://system.data.sqlite.org/downloads/1.0.109.0/sqlite-netFx45-binary-Win32-2012-1.0.109.0.zip

Скопируйте файл SQLite.Interop.dll из этого zip-файла в папку x86 ниже папки вашего проекта.

  1. В вашем проекте Visual Studio добавьте эти три файла в виде ссылок на ваш проект, чтобы он выглядел следующим образом:

enter image description here

  1. В вашем проекте Visual Studio выберите эти три файла и установите для их свойства «Копировать в выходной каталог» значение «Копировать всегда».

  2. В вашем проекте Visual Studio в разделе ссылки удалите ссылку на System.Data.SQLite, если она уже есть, и вместо этого добавьте ссылку на файл System.Data.SQLite.dll, скопированный в каталог проекта. , Установите для свойства «Конкретная версия» значение true.

  3. Сборка проекта.

  4. Теперь вы увидите эту файловую структуру в вашем выходном каталоге, и все будет работать, как ожидается, независимо от того, работает приложение в 32-битном или 64-битном режиме.

enter image description here

  1. Для распространения приложения эти три библиотеки должны быть распределены, сохраняя при этом одинаковую файловую структуру и не регистрируя библиотеки DLL в глобальном кэше сборок.

статически связанный вариант:

Обратите внимание, что после выполнения вышеуказанных шагов вы также должны распространять x86 и x64 версии «Среда выполнения Visual C ++ 2012 Update 4» от Microsoft на клиентских компьютерах. Если вы этого не сделаете, загрузите ZIP-файлы, помеченные как «Предварительно скомпилированные статически связанные двоичные файлы», вместо этого в шагах 4 и 5.

Единственное отличие состоит в том, как два файла с именем SQLite.Interop.dll скомпилированы в этом варианте.


Объяснение на фоне:

Вы можете скачать два различных варианта System.Data.SQLite.dll:

смешанный режим

Существует вариант смешанного режима . В этом варианте эта же dll (System.Data.SQLite.dll) содержит как фактический неуправляемый исходный код SQLite, так и управляемую оболочку .net. Сборки смешанного режима (поскольку они содержат неуправляемый собственный код) во время компиляции связаны с 32-битной или 64-битной средой. Таким образом, существует 32-разрядная версия смешанного режима System.Data.SQLite.dll, а также существует 64-разрядная версия смешанного режима System.Data.SQLite.dll.

Когда вы ссылаетесь на любую из этих двух сборок смешанного режима, ваше приложение может работать только в 32-битном или 64-битном режиме.

удалось только

Тогда существует вариант только для управляемых . В этом варианте System.Data.SQLite.dll содержит только управляемый код оболочки. В этом варианте сборка является ЛЮБОЙ сборкой ЦП. Может использоваться как в 32-битных, так и в 64-битных процессах.

Фактический неуправляемый код SQLite содержится в dll с именем SQLite.Interop.dll. Это родная (неуправляемая, нет .net) dll. Существует 32-битная версия SQLite.Interop.dll. И есть 64-битная версия SQLite.Interop.dll.

Управляемый только вариант System.Data.SQLite.dll определяет архитектуру процессора текущего процесса при загрузке и затем пытается загрузить соответствующий файл SQLite.Interop.dll из подкаталога с именем архитектуры процессора.


Альтернативный подход с использованием глобального кэша сборок

В качестве альтернативы вы можете получить обе версии (32-битной и 64-битной) версии смешанного режима *1141* System.Data.SQLite.dll в смешанном режиме и установить обе в глобальном кэше сборок на компьютере разработчика. и на компьютерах клиентов. Затем ваше приложение автоматически выберет версию с правильной архитектурой процессора из глобального кэша сборок во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...