I wrote a MsBuild Task : MyTask. In my solution, I have the Task project and others projects. MyTask references a project (say ProjA) which references third assemblies, say (dep1 and dep2).
The projects all builds well and I have the outputs in one directory (Compil). In this directory i have all the dll's I want : MyTask.dll, ProjA.dll, dep1.dll, dep2.dll and others.
In my MsBuild file i include the custom task assembly with :
<UsingTask AssemblyFile="..\Compil\MyTask.dll" TaskName="CreateSitesCss" />
Then I call a task of the MyTask assembly. The call is well executed but MsBuild complains about not finding the dep1 and dep2 assemblies (although they are in the same directory) :
error : Could not load file or assembly 'dep1, Version=2.0.0.0, Culture=neutral,PublicKey Token=9109c11469ae1bc7' or one of its dependencies. The system cannot find the file specified.
I can solve this problem by copying dep1.dll and dep2.dll to c:\windows\microsoft .net\framework\v4.0\ but I don't want to do this because it triggers problems when building other projects (won't copy the dep1.dll and dep2.dll to the output directory...).
Has anybody the same problem, or better, a solution?
EDIT
Here is the output of Fusion Log Viewer
*** Assembly Binder Log Entry (19/10/2010 @ 17:52:45) ***
The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.
Assembly manager loaded from: C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = HEADOFFICE\bbaumann
LOG: DisplayName = ProjA
(Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: ProjA | Domain ID: 1
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
LOG: Appbase = file:///c:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = MSBuild.exe
Calling assembly : System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
WRN: Not probing location file:///d:/svn/twilight/_build/ProjA.DLL, because the location falls outside of the appbase.
WRN: Not probing location file:///d:/svn/twilight/_build/ProjA/ProjA.DLL, because the location falls outside of the appbase.
WRN: Not probing location file:///d:/svn/twilight/_build/ProjA.EXE, because the location falls outside of the appbase.
WRN: Not probing location file:///d:/svn/twilight/_build/ProjA/ProjA.EXE, because the location falls outside of the appbase.
LOG: Attempting download of new URL file:///c:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/ProjA.DLL.
LOG: Attempting download of new URL file:///c:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/ProjA/ProjA.DLL.
LOG: Attempting download of new URL file:///c:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/ProjA.EXE.
LOG: Attempting download of new URL file:///c:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/ProjA/ProjA.EXE.
LOG: All probing URLs attempted and failed.
And If I copy MsBuild.exe in the directory where all my dll are, it works fine...
MsBuild does not seem to look for dep1.dll and dep2.dll in my Compil directory even if it finds ProjA.dll within...
EDIT
As to how my bindings are done : MyTask references the ProjA Project by :
<ProjectReference Include="..\ProjA\ProjA.csproj">
<Project>{ED61DCC3-D759-4D44-B802-A6A46F328402}</Project>
<Name>ProjA</Name>
</ProjectReference>
ProjA references the two dependencies by
<Reference Include="dep1, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Dependencies\dep1\dep1.dll</HintPath>
</Reference>
<Reference Include="dep2, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Dependencies\dep2\dep2.dll</HintPath>
</Reference>
There are a couple of work arounds that I could sugest.
ILMerge this will allow you merge several Assemblies together, into one assembly.
You can add the secondary refence to your solution even though you are not using it, this would copy it to your bin folder.
create another Target to run after the compile to copy the missing Assembly to the folder
Hope this helps.
Iain
You might try the Fusion Log Viewer (fuslogvw.exe, installed with VisualStudio) to see which paths are being searched for the assemblies. You may find another folder that can be used instead.
If dep1 and dep2 are third-party assemblies or internal ones that won't change, you could always throw them in the GAC. This is something I generally avoid on a build server, but if you are only using them for build helpers and not production installs it shouldn't be an issue.
Edit: The partial bind might be the cause. Are you using Assembly.Load to use ProjA? From the logs you provided, it looks like it is failing to load ProjA - it is not getting far enough to even try loading dep1 or dep2.