23

我觉得我以前已经解决过这个问题,但我不记得是如何解决的。

我有一个看起来像这样的任务文件(CustomTasks.tasks):

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

它引用了一个程序集(即 Ionic.Zip.dll)。Ionic.Zip.dll 不在 GAC 中(我不希望它在)。它就在我的 CustomTasks.dll 旁边。

我的 sln 文件有一个名为 MSBuild 的目录,其中包含 CustomTasks.tasks、CustomTasks.dll 和 Ionic.Zip.dll。

我有一个引用任务文件并调用自定义任务的 csproj:

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

<MyCustomTask ..... />

在构建时,这会产生:

无法从程序集 ....MyCustomTasks.dll 加载“MyCustomTask”任务。无法加载文件或程序集“Ionic.Zip,......”或其依赖项之一。

4

2 回答 2

28

感到疲倦和沮丧并采取了直接的方法......我认为这与我之前解决问题的方式不同......但这也许会对其他人有所帮助。其他更优雅的解决方案非常受欢迎。

  <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>
于 2012-11-25T07:07:08.407 回答
-1

这实际上很容易解决。将您的自定义构建任务和依赖项放在不同的文件夹中。然后正确加载依赖项。

例如像这样:

<UsingTask AssemblyFile="..\BuildTools\CustomTasks.dll" TaskName="MyCustomTask"/>
于 2015-03-16T13:02:14.680 回答