我有一个项目可以生成32位或64位的版本,并且有对应的32/64位依赖项。我想要能够切换配置并且使用正确的引用,但是我不知道如何告诉Visual Studio使用适当架构的依赖项。
也许我在做错事情,但我希望能够在配置下拉菜单中切换x86和x64,并且引用的DLL是正确的位数。
我有一个项目可以生成32位或64位的版本,并且有对应的32/64位依赖项。我想要能够切换配置并且使用正确的引用,但是我不知道如何告诉Visual Studio使用适当架构的依赖项。
也许我在做错事情,但我希望能够在配置下拉菜单中切换x86和x64,并且引用的DLL是正确的位数。
以下是我在以前的一个项目中所做的事情,这将需要手动编辑 .csproj 文件。您还需要为不同的二进制文件创建单独的目录,最好是彼此同级,并与您正在针对的平台名称相同。
在将单个平台的引用添加到项目后,在文本编辑器中打开 .csproj 文件。在 <Project>
元素内第一个 <ItemGroup>
元素之前添加以下代码,可以帮助确定您正在运行(和构建)哪个平台。
<!-- Properties group for Determining 64bit Architecture -->
<PropertyGroup>
<CurrentPlatform>x86</CurrentPlatform>
<CurrentPlatform Condition="'$(PROCESSOR_ARCHITECTURE)'=='AMD64' or '$(PROCESSOR_ARCHITEW6432)'=='AMD64'">AMD64</CurrentPlatform>
</PropertyGroup>
接下来,针对你的特定平台做出以下更改:
<ItemGroup>
<Reference Include="Leadtools, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.dll</HintPath>
</Reference>
<Reference Include="Leadtools.Codecs, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.Codecs.dll</HintPath>
</Reference>
<Reference Include="Leadtools.ImageProcessing.Core, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.ImageProcessing.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.Entity" />
<!-- Other project references -->
</ItemGroup>
注意使用我们之前定义的$(CurrentPlatform)
属性。您也可以使用条件语句来确定为哪个平台包含哪些程序集。此外,您可能还需要:
$(PROCESSOR_ARCHITEW6432)
和$(PROCESSOR_ARCHITECTURE)
替换为$(Platform)
,以仅考虑项目的目标平台。<Reference>
元素。您应该能够将这些元素拆分为3个不同的item groups:不特定于平台的引用、x86特定引用和x64特定引用。<!-- this group contains references that are not platform specific -->
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<!-- any other references that aren't platform specific -->
</ItemGroup>
<!-- x86 specific references -->
<ItemGroup Condition=" '$(Platform)' == 'x86' ">
<Reference Include="MyComAssembly.Interop">
<HintPath>..\..\lib\x86\MyComAssembly.Interop.dll</HintPath>
</Reference>
<!-- any additional x86 specific references -->
</ItemGroup>
<!-- x64 specific referneces -->
<ItemGroup Condition=" '$(Platform)' == 'x64' ">
<Reference Include="MyComAssembly.Interop">
<HintPath>..\..\lib\x64\MyComAssembly.Interop.dll</HintPath>
</Reference>
<!-- any additional x64 specific references -->
</ItemGroup>
<Reference>
元素。您甚至可以设置虚拟项目,在其中添加x86和x64引用,然后只需将必要的<Reference>
元素从这些虚拟项目文件复制到您的“真实”项目文件中。 <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Reference Include="DLLName">
<HintPath>..\DLLName.dll</HintPath>
</Reference>
<ProjectReference Include="..\MyOtherProject.vcxproj">
<Project>{AAAAAA-000000-BBBB-CCCC-TTTTTTTTTT}</Project>
<Name>MyOtherProject</Name>
</ProjectReference>
</ItemGroup>
xcopy /s /e /y "$(SolutionDir)..\component\v3_NET4\$(PlatformName)\*" "$(SolutionDir)..\component\v3_NET4"
对我来说可以。
使用x86/x64依赖项构建一个.Net应用程序
虽然其他答案提供了根据平台制作不同构建的解决方案,但我给出了一种选择,只需要“AnyCPU”配置并制作一个可以与您的x86和x64 dll一起使用的构建。
在运行时正确解决x86/x64-dlls的问题
步骤:
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
Add this postbuild script to your startup project, use and modify the paths of this script so that it copies all your x86/x64 dlls in corresponding subfolders of your build bin\x86\ bin\x64\
xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX86Dlls $(TargetDir)\x86
xcopy /E /H /R /Y /I /D $(SolutionDir)\YourPathToX64Dlls $(TargetDir)\x64
--> When you would start application now, you get an exception that the assembly could not be found.
Register the AssemblyResolve event right at the beginning of your application entry point
AppDomain.CurrentDomain.AssemblyResolve += TryResolveArchitectureDependency;
withthis method:
/// <summary>
/// Event Handler for AppDomain.CurrentDomain.AssemblyResolve
/// </summary>
/// <param name="sender">The app domain</param>
/// <param name="resolveEventArgs">The resolve event args</param>
/// <returns>The architecture dependent assembly</returns>
public static Assembly TryResolveArchitectureDependency(object sender, ResolveEventArgs resolveEventArgs)
{
var dllName = resolveEventArgs.Name.Substring(0, resolveEventArgs.Name.IndexOf(","));
var anyCpuAssemblyPath = $".\\{dllName}.dll";
var architectureName = System.Environment.Is64BitProcess ? "x64" : "x86";
var assemblyPath = $".\\{architectureName}\\{dllName}.dll";
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
return null;
}
好处:
缺点: - 当x86 / x64 dll不匹配时,编译时没有错误。 - 您仍应在两种模式下运行测试!
可选地,在postbuild脚本中使用Corflags.exe创建第二个仅适用于x64架构的可执行文件
其他变体尝试: - 如果您确保将dll复制到启动时的二进制文件夹中(评估进程架构->将相应的dll从x64 / x86移动到bin文件夹中并返回),则无需使用AssemblyResolve事件处理程序。 - 在安装程序中评估架构,并删除错误架构的二进制文件并将正确的文件移到bin文件夹中。