Подтвердить что ты не робот

Варианты использования System.Data.SQLite в 32-битном и 64-битном С# мире

Я понимаю, ПОЧЕМУ System.Data.SQLite.dll предоставляется в 32-битных и 64-битных сборках. Поэтому давайте не будем останавливаться на этом и двигаться дальше.:)

Так как это делается таким образом, кажется, что создание С# для разработки немного сложнее с 3 вариантами.

  • Поддерживается только 32-битное и принудительное управление сборка для компиляции x86 и справиться с этим при работе в 32 или 64 бит, и там, теряя преимущества, когда вы находитесь на 64-битной Окружающая среда.

  • Является силовым 64-битным и поддерживает только 64 бит и проигрывает умение работать на 32 бит, но все преимущества 64 бит.

  • Создать две версии их сборки, которые компилирует x86 и использует 32-разрядный SQLite и другой, который компилирует x64 и использует 64-битный SQLite. Он предотвращает использование "ЛЮБОГО" в качестве параметра компиляции и возможность легко развертывать одну сборку для любого типа. это не так ужасно управлять с точки зрения развития, как мы потребуются два проекта. Только имея код С# официально в одном, а другой будет просто использовать "ссылки" для кода в другом. Эта предназначен только для целей компиляции. Все еще оставляет нас с необходимостью управлять двумя выходами для развертывания.

При всем том, что я говорю только о том, что я только подтверждаю, что вышеизложенное является единственным правильным выбором.

Если есть другие варианты, которые я пропускаю, дайте мне знать. В частности, если есть способ получить единственную DLL С#, которая может скомпилировать ЛЮБОЙ, чтобы она могла использовать 32 или 64 бит в зависимости от того, где ее запускать и по-прежнему использовать System.Data.SQLite.dll.

4b9b3361

Ответ 1

Существует два распространенных решения для хранения вашего основного приложения в AnyCPU:

  • Установите как сборку x86, так и x64 в GAC: они могут (должны!) иметь идентичные имена сборок, и GAC автоматически решит, использовать ли версию x86 или x64.

  • Подключитесь к AppDomain.AssemblyResolve и выполните правильные сборки из подкаталогов с помощью Assembly.LoadFrom

Ответ 2

Это разработка ответа от Springy76. Сделайте это:

public class AssemblyResolver
{
    public static void HandleUnresovledAssemblies()
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += currentDomain_AssemblyResolve;
    }

    private static Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        if (args.Name == "System.Data.SQLite")
        {
            var path = Path.Combine(pathToWhereYourNativeFolderLives, "Native");

            if (IntPtr.Size == 8) // or for .NET4 use Environment.Is64BitProcess
            {
                path = Path.Combine(path, "64");
            }
            else
            {
                path = Path.Combine(path, "32");
            }

            path = Path.Combine(path, "System.Data.SQLite.DLL");

            Assembly assembly = Assembly.LoadFrom(path);
            return assembly;
        }

        return null;
    }
}

Убедитесь, что созданные пути указывают на правильные расположения для ваших 32-разрядных или 64-разрядных SQLite-библиотек. Лично у меня были хорошие результаты с результатами в этом пакете NuGet: http://www.nuget.org/packages/SQLitex64

(Вам нужно всего лишь использовать пакет NuGet, чтобы достать скомпилированные SQLite Dlls. После того, как вы их получите, удалите ссылку на SQLite в своем проекте, созданном NuGet и самим пакетом NuGet. Действительно, оставив ссылку на месте может помешать этому решению, поскольку SQLite никогда не будет признан неразрешенной сборкой.)

Вызовите "HandleUnresolvedAssemblies()" как можно раньше, желательно во время любой начальной загрузки.

Ответ 3

Аналогичная проблема существует с Oracle ODP.NET по сравнению с родными 32/64-разрядными DLL-библиотеками OCI.

Мы решили это, установив платформу "x86" и "x64" для нашего проекта, а затем вручную отредактировав наш файл проекта, чтобы использовать условные ссылки:

<Choose>
<When Condition="'$(Platform)' == 'x64'">
  <ItemGroup>
    <Reference Include="Oracle.DataAccess, processorArchitecture=x64">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\ThirdParty\ODP.NET\x64\Oracle.DataAccess.dll</HintPath>
    </Reference>
    <Content Include="..\ThirdParty\ODP.NET\x64\oci.dll">
      <Link>oci.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x64\orannzsbb11.dll">
      <Link>orannzsbb11.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x64\oraociei11.dll">
      <Link>oraociei11.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x64\OraOps11w.dll">
      <Link>OraOps11w.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
</When>
<When Condition="'$(Platform)' == 'x86'">
  <ItemGroup>
    <Reference Include="Oracle.DataAccess, processorArchitecture=x86">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\ThirdParty\ODP.NET\x86\Oracle.DataAccess.dll</HintPath>
    </Reference>
    <Content Include="..\ThirdParty\ODP.NET\x86\oci.dll">
      <Link>oci.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x86\orannzsbb11.dll">
      <Link>orannzsbb11.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x86\oraociei11.dll">
      <Link>oraociei11.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
    <Content Include="..\ThirdParty\ODP.NET\x86\OraOps11w.dll">
      <Link>OraOps11w.dll</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
</When>
</Choose>

Это позволило нам избежать использования двух разных проектов. Я уверен, что вы можете сделать что-то подобное для SQLite.

Ответ 4

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

Это неверно - вы можете использовать две конфигурации сборки в одном проекте. Во время развертывания вам нужно будет построить как для x86, так и для x64, но база кода и проект могут быть одинаковыми.

В настоящее время я делаю это в более крупном производственном проекте, как из-за SQLite, так и в других родных/межсетевых библиотеках, которые включают варианты x64 и x86.

Ответ 5

Обычно вариант - это вариант, если вашему приложению не требуется больше 4 ГБ памяти. Помните, что 32-битное приложение на 64-битной ОС имеет большинство преимуществ 64-битного без многих недостатков. Вот почему x86 является целевой по умолчанию для приложений .exe в VS 2010.

Ответ 6

Бранко Димитриевич сказал: "Я уверен, что вы можете сделать что-то подобное для SQLite". И это правильно.:)

Имея ту же самую проблему, я нашел вопрос Родни, и Бранко ответил и попробовал это сам. Для тех, кто хочет увидеть мою рабочую реализацию SQLite, вы здесь:

<Choose>
  <When Condition="'$(Platform)' == 'x64'">
    <ItemGroup>
      <Reference Include="System.Data.SQLite, Version=1.0.88.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64">
        <SpecificVersion>False</SpecificVersion>
        <HintPath>System.Data.SQLite\x64\System.Data.SQLite.dll</HintPath>
      </Reference>
    </ItemGroup>
  </When>
  <When Condition="'$(Platform)' == 'x86'">
    <ItemGroup>
      <Reference Include="System.Data.SQLite, Version=1.0.88.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64">
        <SpecificVersion>False</SpecificVersion>
        <HintPath>System.Data.SQLite\x86\System.Data.SQLite.dll</HintPath>
      </Reference>
    </ItemGroup>
  </When>
</Choose>

<ItemGroup>
  <Reference Include="Microsoft.CSharp" />
  <Reference Include="System" />
  <Reference Include="System.configuration" />
  <Reference Include="System.Core" />
  <Reference Include="System.Windows.Forms" />
  <Reference Include="System.Xml.Linq" />
  <Reference Include="System.Data.DataSetExtensions" />
  <Reference Include="System.Data" />
  <Reference Include="System.Xml" />
</ItemGroup>

Конечно, вы можете назвать HintPath тем, что вам нравится.

Я нашел, что это идеальное решение: я могу поддерживать один проект и быстро переключаться между целевыми платформами по мере необходимости. Единственным потенциальным недостатком я не вижу ссылку в обозревателе решений. Но это небольшая цена для оплаты всей функциональности.

Ответ 7

Вы также можете решить эту проблему, изменив параметры компиляции в Visual Studio:

Чтобы изменить параметры компиляции в Visual Studio:

  • Перейдите в проект запуска вашей программы.
  • Откройте окно свойств.
  • Перейдите на вкладку компиляции.
  • Выберите расширенные параметры компиляции.
  • Измените параметры целевого процессора на x86.

Ваша программа теперь будет работать в 32-битном режиме, даже если она запускается на 64-битной машине.

Вы также можете предоставить два дистрибутива, по одному для каждой среды, как указано выше. Хотя это станет стандартом в будущем, для моего текущего проекта это был лучший и самый простой вариант.