MSBuild UsingTask Resolve References

Jeff picture Jeff · Nov 25, 2012 · Viewed 9.9k times · Source

I feel like I've fixed this before, but I can't remember how.

I have a tasks file that looks like this (CustomTasks.tasks):

<UsingTask AssemblyFile="CustomTasks.dll" TaskName="MyCustomTask"/>

it references an assembly (namely Ionic.Zip.dll). Ionic.Zip.dll is not in the GAC (and I don't want it to be). It sits right next to my CustomTasks.dll.

I have a directory called MSBuild one level up from my sln file which has CustomTasks.tasks, CustomTasks.dll and Ionic.Zip.dll in it.

I have a csproj that references the tasks file and calls the custom task:

<Import Project="$(ProjectDir)\..\MSBuild\CustomTasks.tasks" />

<MyCustomTask ..... />

at build time, this yields:

The "MyCustomTask" task could not be loaded from the assembly ....MyCustomTasks.dll. Could not load file or assembly 'Ionic.Zip,......' or one of its dependencies.

Answer

Jeff picture Jeff · Nov 25, 2012

Got tired and frustrated and took a direct approach...I don't think this is the same way I solved the problem previously...but maybe this will help someone else. Other, more elegant solutions are more than welcome.

  <Target Name="BeforeBeforeBuild" BeforeTargets="BeforeBuild">
    <HandleAssemblyResolve SearchPath="$(ProjectDir)\..\MSBuild\" />
  </Target>
  <UsingTask TaskName="HandleAssemblyResolve" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <ParameterGroup>
      <SearchPath ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Using Namespace="System" />
      <Using Namespace="System.IO" />
      <Using Namespace="System.Reflection" />
      <Code Type="Fragment" Language="cs">
        <![CDATA[
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => 
{ 
  var assemblySearchPath = Path.Combine(SearchPath, e.Name.Split(',')[0]);
  if (File.Exists(assemblySearchPath)) return Assembly.LoadFrom(assemblySearchPath);

  return null;
};
]]>
      </Code>
    </Task>
  </UsingTask>