MSBuild使用任务(UsingTask)解析引用

23

我感觉我以前已经修过这个问题,但是我不记得怎么做了。

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

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

它引用了一个程序集(即Ionic.Zip.dll)。Ionic.Zip.dll不在全局程序集缓存(GAC)中(我也不想让它在那里),它就在我的CustomTasks.dll旁边。

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

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

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

<MyCustomTask ..... />

在构建时,这将产生:

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

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>

1
嘿 - 我正要写这段几乎相同的代码(或者类似的东西),然后决定在 Stack Overflow 上寻找其他解决问题的方法...谢谢,这非常有用! - JerKimball
8
这个MSBuild关于引用的问题真的让持续集成非常痛苦。 - Johnny_D
@JerKimball,我正在寻找类似的方法,您能解释一下这里的searchpath是什么吗? - ansar
1
谢谢提供的解决方案。我只需要将 + ".dll" 添加到第一行代码即可。 - honzajscz

-1

这个问题其实很容易解决。把你的自定义构建任务和依赖关系放在一个不同的文件夹中,然后依赖关系就会被正确地加载。

例如:

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

5
这个不起作用。只有汇编文件本身被正确加载。即使依赖项在同一个文件夹中,也无法找到程序集的任何依赖项。至少这是我使用msbuild和这种方法的经验。 - theta-fish
也许你应该试一下 - 我用 MSBuild 4 成功了,这就是我在这里留下评论的原因。 - Bernd
1
我想我在陈述时应该少些绝对性,而不是说“这行不通”,但或许你应该有时间读一下评论。我说过“这是我使用msbuild和这种方法的经验”,这当然意味着我试过了。我怀疑其他因素帮助了你的构建,而不是你所认为的,但我不知道你的配置或环境,所以我不知道那是什么。将程序集放在同一个文件夹中并不能达到预期的效果,因为Fusion程序集加载器不会在那里查找它们。所选解决方案幸运地是可行的修复方法。 - theta-fish
1
坦白地说,我希望这对我有用。这将显示汇编加载方面的一些智能。 - theta-fish
我在本地测试成功了,但是在AppVeyor上运行时失败了。我的任务程序集与一个外部依赖项在同一个文件夹中,但是由于某种原因,MSBuild并不总是能够正确识别它。 - Matthew Olenik
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接