Search code examples
visual-studio-2010xpathantmsbuildxmltask

MSBuild: changing project references to file binary references


I have a few .net / C# projects that I'm building with MSBuild.

In the project I'm building, there are some project references to other C# projects.

I'm only building individual projects, so I'd like to repoint the project references to actual binaries in a folder during the build.

I'm already setting "BuildProjectReferences" to False for my MSBuild step.

So essentially I want to have MSBuild ignore the project refs and look for those binaries in a new directory.

Is this possible to do? Is this possible without having to dynamically modify the project file prior to build?

** Update 1 **

More info might help...I'm actually building each binary via Ant/AntDotNet/MSBuild and uploading to Artifactory. I'm basically using Ivy's dependency management with .Net binaries.

Right now I have the uploads and downloads of dependencies working fine.

The only part I'm missing is getting MSBuild to look for the binaries as file dependencies instead of the project references that it has in the project file.

** Update 2 **

It looks like MSBuild supports editing the csproj file using XMLPoke and XMLPeek.

So in my case I'd need to change the following in my project file:

<ProjectReference Include="..\MyReferencedProject\MyReferencedProject.csproj">
  <Project>{MyReferencedProjectGUID}</Project>
  <Name>MyReferencedProject</Name>
  <Private>False</Private>
</ProjectReference>

to this

<Reference Include="MyReferencedProject">
</Reference>

Can anyone give me any pointers on that?


Solution

  • I ended up using Ant combined with the xmltask addon.

    <target name="convert" description="convert project references to file references">
        <echo>Converting the following Project references :: ${Project.ItemGroup.ProjectReference.Name}</echo>
        <xmltask source="MyParentProject.csproj" dest="MyParentProject.csproj">
            <rename path="/:Project/:ItemGroup/:ProjectReference/:Name" to="BinaryName"/>
        </xmltask>
        <replace file="MyParentProject.csproj" token="&lt;BinaryName&gt;" value="&lt;Reference Include=&quot;"/>
        <replace file="MyParentProject.csproj" token="&lt;/BinaryName&gt;" value="&quot;&gt;&lt;/Reference&gt;"/>
        <xmltask source="MyParentProject.csproj" dest="MyParentProject.csproj">
            <copy path="/:Project/:ItemGroup/:ProjectReference/:Reference" buffer="refbuffer" append="true"/>
            <paste path="/:Project/:ItemGroup[1]" buffer="refbuffer"/>
            <remove path="/:Project/:ItemGroup/:ProjectReference" /> 
        </xmltask>
        <echo>Conversion complete.</echo>
    </target>
    

    In the first xmltask we are setting the "Name" element to "BinaryName" so we can find it.

    Next we have two Ant Replace tasks that change something like

    "<BinaryName>MyReferencedProject</BinaryName>" 
    

    to

    "<Reference Include="MyReferencedProject"></Reference>"
    

    And in the last xmltask moves our project references we converted into file references into the upper ItemGroup that normally has the file references.

    Then finally we delete the ProjectReferences section.