MSBuild Inline Task - Reference non-standard Micro

2019-02-11 22:52发布

问题:

I am using the new MSBuild Inline Task to leverage the TransformXml (XDT Transform) in the Microsoft.Web.Publishing.Tasks.dll assembly.

Here's what my task (snipped) looks like:

<Task>
  <Reference Include="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
  <Reference Include="System.Xml" />
  <Using Namespace="System"/>
  <Using Namespace="System.Linq"/>
  <Using Namespace="System.IO" />
  <Using Namespace="System.Xml"/>
  <Using Namespace="Microsoft.Web.Publishing.Tasks"/>
  <Code Type="Fragment" Language="cs">...</Code>
</Task>

This compiles fine and the DLL is loaded, however, when executed it fails because it is trying to find the assembly in the appbase path which is: C:\Windows\Microsoft.NET\Framework\v4.0.30319. I would have expected it to look at the path I gave it.

Fusion log shows this:

=== Pre-bind state information ===\r
  LOG: User = xxx\Kamran\r
  LOG: DisplayName = Microsoft.Web.Publishing.Tasks, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
   (Fully-specified)\r
  LOG: Appbase = file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/\r
  LOG: Initial PrivatePath = NULL\r
  Calling assembly : (Unknown).\r
  ===\r
  LOG: This bind starts in default load context.\r
  LOG: Using application configuration file: C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe.Config\r
  error MSB4018: LOG: Using host configuration file: \r
  error MSB4018: LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.\r
  error MSB4018: LOG: Post-policy reference: Microsoft.Web.Publishing.Tasks, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\r
  error MSB4018: LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Microsoft.Web.Publishing.Tasks.DLL.\r
  error MSB4018: LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Microsoft.Web.Publishing.Tasks/Microsoft.Web.Publishing.Tasks.DLL.\r
  error MSB4018: LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Microsoft.Web.Publishing.Tasks.EXE.\r
  error MSB4018: LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/Microsoft.Web.Publishing.Tasks/Microsoft.Web.Publishing.Tasks.EXE.\r

Is there any way to fix this or will I be forced to create a task assembly instead?

回答1:

I would still like a real answer to this, but I was able to workaround this issue using reflection and just loading the assembly.

You can see the full source in my gist.



回答2:

According to this article in Dzone: Web.config transformations you must add

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>

just in the head of MSBuild file. It seems that MSBuild does not find it and trying to load from GAC



回答3:

Another work around is using AppDomain.AssemblyResolve. However, you will then have to register your handler before the framework needs the assembly.

This can be done by putting everything in an Action delegate inside the fragment. Another possibility is setting the 'Type' attribute of the 'Code' element to 'class' instead of 'fragment'.

For information about using AssemblyResolve there is already an article on stackoverflow: How to add folder to assembly search path at runtime in .NET?.

Still not ideal, but in my case cleaner than reflection.