Как подключить две версии одной библиотеки в Any CPU
одна версия под x64, другая под 32. имя библиотек совпадает Как правильно или более удобно их можно обе подключить?
дополнение: посмотрел по предложенной ссылке в ответе. сделал новое консольное приложение, добавил согласно материалу ссылку на одну из версий библиотеки, после этого скопировал файл проекта в другую папку и открыл в визуал студии для редактирования. Файл до редактирования:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7A0D5B4B-293F-44C3-96BF-4A0AB01F2DFF}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>TestBd4</RootNamespace>
<AssemblyName>TestBd4</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite">
<HintPath>..\..\..\..\Desktop\библиотеки\crypt\x64\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
согласно материалу по ссылке - ... Используйте четыре элемента ItemGroup со всеми сочетаниями параметров, как показано далее.
отредактировал и получил файл с содержанием:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7A0D5B4B-293F-44C3-96BF-4A0AB01F2DFF}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>TestBd4</RootNamespace>
<AssemblyName>TestBd4</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64'">
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite">
<HintPath>..\..\..\..\Desktop\библиотеки\crypt\x64\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64'">
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite">
<HintPath>..\..\..\..\Desktop\библиотеки\crypt\x64\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86'">
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite">
<HintPath>..\..\..\..\Desktop\библиотеки\crypt\Win32\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64'">
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite">
<HintPath>..\..\..\..\Desktop\библиотеки\crypt\Win32\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
после чего заменяю файл проекта в папке с приложением и получаю следующее:
Ответы (2 шт):
Можно прописать соответствующие Conditions для ItemGroup в файле вашего проекта:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64'">
<Reference Include="ClassLibrary1">
<HintPath>..\path\x64\ClassLibrary1.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86'">
<Reference Include="ClassLibrary1">
<HintPath>..\path\x86\ClassLibrary1.dll</HintPath>
</Reference>
</ItemGroup>
Подробнее по ссылке
Можно так:
Добавляем ссылку на библиотеку.
У ссылки ставим Копировать локально = False
Делаем так, чтобы две версии библиотеки лежали в подкаталогах x86 и x64 выходного каталога. Т.е. структура должна быть такой:
MyProject\MyProject.csproj
MyProject\bin\Debug\MyProject.dll
MyProject\bin\Debug\x86\MyLib.dll
MyProject\bin\Debug\x64\MyLib.dll
- В коде делаем следующее:
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace ConsoleApp1
{
class MyClass
{
static MyClass()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
AssemblyName name = new AssemblyName(args.Name);
string basepath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (Environment.Is64BitProcess)
basepath = Path.Combine(basepath, "x64");
else
basepath = Path.Combine(basepath, "x86");
Assembly ret = Assembly.LoadFrom(Path.Combine(basepath, name.Name + ".dll"));
return ret;
}
public static void Method()
{
//работа с библиотекой
}
}
}
Суть способа в том, чтобы перехватить событие разрешения сборки и подсунуть разную версию в зависимости от разрядности. Обязательное условие - чтобы непосредственно в каталоге с программой не было никакой версии MyLib.dll, т.е. стандартный алгоритм разрешения должен завершиться с ошибкой. Иначе наш обработчик не запустится. Обработчик должен быть прицеплен до объявления любой переменной из библиотеки, поэтому он помещен в статическом конструкторе. Таким образом это можно заставить работать с AnyCPU.
