Search code examples
msbuildmsbuild-task

MSBuild UsingTask Resolve References


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.


Solution

  • 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>