none
MSBuild Resolve Project Reference to Assembly

    Question

  • Hello!

    Currently I'm working on a code-validation tool, realized by a custom MSBuild Task, which is called by the target "BeforeBuild".

    For validation, I have to scan all the cs-files belonging to the project and resolve all accesses to foreign assemblies.
    But to do this, I need to know which assemblies are referenced by the current project.
    By passing the "reference" elements I can resolve the most direct references to their location, as the location of the assembly is stored in the hint-property.
    Sadly, I am not able to resolve the "project-reference" elements to their corresponding assembly-filepaths, as only the csproj-path is supplied.

    The definition of my custom task looks as following:

    <MyValidationTask Files="@(Compile)" ProjectReferences="@(ProjectReference)" References="@(Reference)" />
    I want to resolve the "project-reference" into a file-path: Through the "ProjectReferences" property of my task, I get only an array of ITaskItem. But how can I get the file path to the assembly (i.e. the compiled project in the same solution) from this ITaskItem object? There is no property like HintPath, in contrast to the normal "References" ITaskItem.


    An example:
    I want to get this:

    H:\Informatik\C#\SharedAssemblies\HDUnitsOfMeasure\HDUnitsOfMeasureValidator\bin\Debug\HDUnitsOfMeasureValidator.dll

    from this:

    <ProjectReference Include="..\HDUnitsOfMeasureValidator\HDUnitsOfMeasureValidator.csproj"> <Project>{50D3B367-102B-45E9-8917-C7F7D0BC6565}</Project> HDUnitsOfMeasureValidator </ProjectReference>

    I've asked the same question on Codeproject some time ago, but didn't get an answer.

    Thanks for answering,
    Henning

    Sunday, July 01, 2012 10:19 AM

Answers

  • Hi Henning,

    Here's a test target showing how to access the resolved assembly reference's list:

      <Target Name="PrintReferences" DependsOnTargets="ResolveProjectReferences;ResolveAssemblyReferences">
    	<Message Text="File Names:" Importance="high" />
    	<Message Text="@(Reference->'%(FileName)')" />
    	<Message Text="Assembly References:" Importance="high" />
    	<Message Text="@(_ResolveAssemblyReferenceResolvedFiles)" />
    	<Message Text="Search Paths:" Importance="high" />  
    	<Message Text="$(AssemblySearchPaths)" />
      </Target>

    ResolveAssemblyReferences is a target defined in Microsoft.Common.targets that gets automatically imported to your VS project file, and _ResolveAssemblyReferenceResolvedFiles holds the output.

    For a simple test you could use a command line like:

    msbuild [YourApp].csproj /t:PrintReferences /nologo

    Marcel

    Monday, July 02, 2012 6:26 AM

All replies

  • Hi Henning,

    I think you have got the references as a taskitem[] list. And you want to use them as an assembly. However I can't see the output in your usingtask. The three attributes in your myvalidation task are all required.

    And I also can't understand what your example means. If you just want to use H:\Informatik\C#\SharedAssemblies\HDUnitsOfMeasure\HDUnitsOfMeasureValidator\bin\Debug\HDUnitsOfMeasureValidator.dll.

    You can define <ProjectReference Include="..\HDUnitsOfMeasureValidator\HDUnitsOfMeasureValidator.dll" />

    Then you can write @(ProjectReference)  to use it.

    Here is some codes I wrote which may be useful to you:

        public class MyValidationTask : Task

        {

            private List<TaskItem> TestTaskList = new List<TaskItem>(); 

            [Output] 

            public ITaskItem[] MyOutput 

           { 

                get { return TestTaskList.ToArray(); } 

            }

           ...

       }

    ----------------------------------------------------------------------------

    <MyValidationTask>

        <Output MyOutput="MyOutput"/>

    </MyValidationTask>

    -----------------------------------------------------------------------------

    Best regards,


    Ego [MSFT]
    MSDN Community Support | Feedback to us

    Monday, July 02, 2012 3:00 AM
  • Hi Henning,

    Here's a test target showing how to access the resolved assembly reference's list:

      <Target Name="PrintReferences" DependsOnTargets="ResolveProjectReferences;ResolveAssemblyReferences">
    	<Message Text="File Names:" Importance="high" />
    	<Message Text="@(Reference->'%(FileName)')" />
    	<Message Text="Assembly References:" Importance="high" />
    	<Message Text="@(_ResolveAssemblyReferenceResolvedFiles)" />
    	<Message Text="Search Paths:" Importance="high" />  
    	<Message Text="$(AssemblySearchPaths)" />
      </Target>

    ResolveAssemblyReferences is a target defined in Microsoft.Common.targets that gets automatically imported to your VS project file, and _ResolveAssemblyReferenceResolvedFiles holds the output.

    For a simple test you could use a command line like:

    msbuild [YourApp].csproj /t:PrintReferences /nologo

    Marcel

    Monday, July 02, 2012 6:26 AM
  • Thank you very much for your responses!

    I've forgotten to mention, that I asked the same question in the German MSDN-Forum.

    @Marcel:

    That's the solution, thank you!

      <Target Name="BeforeBuild" DependsOnTargets="ResolveProjectReferences;ResolveAssemblyReferences">
        <UnitValidationTask Files="@(Compile)" References="@(_ResolveAssemblyReferenceResolvedFiles)" />
      </Target>

    @Ego Jiang:

    Why is the output-attribute required? I works without, too...

    And the reason for not specifying the exact file path to the assembly within the cs-project, is that it would change the vocation of the project-reference element. Nevertheless, the problem is solved and I'm very happy ;)

    Monday, July 02, 2012 9:39 AM