'Azure DevOps build task VSBuild copies DLL marked as copy=false
I'm currently trying to create a CD pipeline with Azure DevOps with a solution using .NET Framework 4.8 and Oracle.
Unfortunately, I can't make it run; as the DLL Oracle.DataAccess
is in the GAC, I need to make sure the build-pipeline doesn't package it, otherwise I get the error:
Could not load file or assembly 'Oracle.DataAccess, Version=4.121.19.1, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Now, what's interesting: To make it work locally, I have the Oracle.DataAccess
DLL copied to a local folder, but reference it with "Copy Local = False":
<Reference Include="Oracle.DataAccess, Version=4.122.19.1, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\librairies\Oracle.DataAccess.dll</HintPath>
<Private>False</Private>
</Reference>
Now, when compiling locally, everything is fine and the DLL is not copied locally, but when I build on Azure DevOps, I always get the DLL in the final package and I see the following log-entry:
_CopyFilesMarkedCopyLocal: Copying file from "C:...\19.0.0\client_1\odp.net\bin\4\Oracle.DataAccess.dll" to "Path\bin\Release\Oracle.DataAccess.dll".
The Azure DevOps YAML looking like this:
variables:
solution: 'src/**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
...
- task: VSBuild@1
displayName: 'Build solution'
inputs:
solution: '$(solution)'
vsVersion: '16.0'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
msbuildArchitecture: 'x64'
createLogFile: true
Checking with TotalCmd and the likes, I don't see any hidden dependency to the Oracle.DataAccess
DLL in the codebase. It seems like the VSBuild Task kinda how wants to copy the file anyway, although me saying it shouldn't. Is there anything I'm not seeing hereby? Or is there a significant difference in how the VSBuild task behaves? I didn't find anything specific in the documentation about such behavior.
Solution 1:[1]
As workaround you could delete the file manually. Edit your .csproj
with a text editor and add this line:
<Target Name="AfterBuild">
<Delete Files="$(OutputPath)Oracle.DataAccess.dll" />
</Target>
Solution 2:[2]
I randomly found a solution, but I'm not sure if it's a hack or intended. When I configure the referenced assembly directly in the host assembly like this:
<Reference Include="Oracle.DataAccess, Version=x.x.x.x, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\librairies\Oracle.DataAccess.dll</HintPath>
<Private>False</Private>
</Reference>
It works out and the publishing doesn't copy it. I would tend to think this is a bug of the task kinda how, as locally publish doesn't copy the assembly and I would guess, that having a transient dependency with copy=false should honor this as well. Also, having a reference to the data access assembly in the host assembly (like web API) isn't a nice separation of concerns.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Wernfried Domscheit |
Solution 2 | Matthias Müller |