VS2022中如何阻止F#复制间接引用的程序集至bin目录?
问题:F#项目构建时自动复制所有间接引用程序集,C#项目无此现象
使用VS 2022构建F#项目时,目标程序集的所有间接引用都会被自动复制到bin目录;而相同逻辑的C#项目构建后,bin目录仅包含生成文件及显式指定Copy Local(对应Private=True)的引用程序集。即使两个项目中目标引用的Private属性均设置为False,F#项目仍会复制所有间接引用,尝试修改Private属性、调整配置项、手动添加自动复制的DLL到项目均无法解决问题。
原因分析
这是F# SDK风格项目与传统非SDK风格C#项目在依赖处理逻辑上的差异:
- 提供的C#项目采用传统非SDK格式(基于
Microsoft.CSharp.targets),对引用的复制逻辑更严格:仅复制显式标记Private=True的引用,且不会自动递归复制间接依赖。 - F#项目采用**.NET SDK格式**,默认会通过依赖解析系统自动解析并复制所有直接和间接依赖的程序集到输出目录,即使显式设置
Private=False,间接引用的处理逻辑仍与C#非SDK项目不同。
解决方案
方案1:禁用自动复制所有依赖程序集
在F#项目的<PropertyGroup>中添加以下配置,让项目仅复制显式标记Private=True的引用,与C#非SDK项目行为一致:
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
方案2:逐个排除引用的间接运行时依赖
对于不需要复制的引用,添加<ExcludeAssets>runtime</ExcludeAssets>属性,阻止其间接依赖被复制:
<Reference Include="EncompassObjects"> <HintPath>C:\Program Files (x86)\Encompass\EncompassObjects.dll</HintPath> <Private>False</Private> <ExcludeAssets>runtime</ExcludeAssets> </Reference>
原始项目文件
C#项目文件(.csproj)
<?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>{B9485712-4A8F-4894-8268-003BC72149C3}</ProjectGuid> <OutputType>Exe</OutputType> <RootNamespace>ConnectTest</RootNamespace> <AssemblyName>ConnectTest</AssemblyName> <TargetFrameworkVersion>v4.8</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="EllieMae.Encompass.AsmResolver"> <HintPath>C:\Program Files (x86)\Encompass\EllieMae.Encompass.AsmResolver.dll</HintPath> </Reference> <Reference Include="EllieMae.Encompass.Runtime"> <HintPath>C:\Program Files (x86)\Encompass\EllieMae.Encompass.Runtime.dll</HintPath> </Reference> <Reference Include="EncompassObjects"> <HintPath>C:\Program Files (x86)\Encompass\EncompassObjects.dll</HintPath> <Private>False</Private> </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> <Reference Include="Microsoft.CSharp" /> </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>
F#项目文件(.fsproj)
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net48</TargetFramework> <WarnOn>3390;$(WarnOn)</WarnOn> </PropertyGroup> <ItemGroup> <Compile Include="Program.fs" /> </ItemGroup> <ItemGroup> <Reference Include="ClientServer"> <HintPath>C:\Program Files (x86)\Encompass\ClientServer.dll</HintPath> <Private>True</Private> </Reference> <Reference Include="EllieMae.Encompass.AsmResolver"> <HintPath>C:\Program Files (x86)\Encompass\EllieMae.Encompass.AsmResolver.dll</HintPath> <Private>True</Private> </Reference> <Reference Include="EllieMae.Encompass.Runtime"> <HintPath>C:\Program Files (x86)\Encompass\EllieMae.Encompass.Runtime.dll</HintPath> <Private>True</Private> </Reference> <Reference Include="EncompassObjects"> <HintPath>C:\Program Files (x86)\Encompass\EncompassObjects.dll</HintPath> <Private>True</Private> </Reference> </ItemGroup> </Project>
内容的提问来源于stack exchange,提问作者Dale Hurtt
相关产品推荐
相关产品推荐

