none
How to Access MSBuild properties inside custom task RRS feed

  • Question

  • Hello,

    I have implemented a custom task (Subclass of Microsoft.Build.Utilities.Task) and I am looking for the best way to access MSBuild properties, such as $(TargetPath), $(ConfigurationName), $(OutDir) etc. inside the code of the task.

    Is it possible without passing them explicitly?

     

    Monday, February 4, 2013 1:02 AM

Answers

  • If you pass the project filename to your task a a required property, you can use it to find the currently executing project but it requires reflection to extract the info from the build engine.  As such, it's rather messy and is dependent on the version of MSBuild you are using so bear that in mind as future versions of MSBuild may change and cause the code to break.  Once you've got the project reference though, you can access it as usual to retrieve its properties and items.

    Here's an example that works in MSBuild 4.0: http://shfb.codeplex.com/SourceControl/changeset/view/101283#2015117

    Here's an example that works in MSBuild 2.0 and 3.5: http://shfb.codeplex.com/SourceControl/changeset/view/85384#1673590

    See the Execute() and GetCurrentProject()/GetCurrentProjectInstance() methods in each.

    I wasn't aware of the build logger approach and, if that is viable, it would probably be the better option in the long run as it wouldn't be dependent on the inner workings of the build engine.

    Eric

    Tuesday, February 5, 2013 8:37 PM

All replies

  • Hi Maxim,

    I guess you want to transfer the values of the properties. We can add the [Required] attribute in your custom task and set the value when you using the task.

    If you want to learn more about it, please view the blog below:

    http://blogs.msdn.com/b/msbuild/archive/2006/01/21/515834.aspx

    Best regards, 


    Ego [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, February 5, 2013 7:08 AM
    Moderator
  • Yes, I'm aware of the way to pass values of the project's properties through the properties of the Task, but this means that I need to pass each of them individually, I was hoping that as Task is instantiated in the context of the MSBuild environment it will have access to some kind of collection with all properties available in the project, similar to the situation you have in the pre/post build event, where you can use any property defined in the project.

     
    Tuesday, February 5, 2013 7:15 AM
  • Hi,

    I don't think we can get all the properties of project in a custom task.

    As I know, we can use the Visual Studio SDK Interop assemblies like: Microsoft.VisualStudio.Shell.Interop.IVsHierarchy,Microsoft.VisualStudio.Shell.Interop.IVsProject to access project hierarchy. However we should create a VSPackages to implement project hierarchies.

    If you are interested, here is a blog you can refer to:

    http://blogs.clariusconsulting.net/pga/how-do-i-get-a-project-from-a-ivshierarchy-and-viceversa/

    In this case, I think you can only get the properties by input manually.

    Best regards,


    Ego [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, February 5, 2013 8:14 AM
    Moderator
  • I think this design is intentional on MSBuild side. When I tried something similar a while back, the closest option I found was to create a custom logger (which does have access to all properties) and access it from the custom task.
    Tuesday, February 5, 2013 4:33 PM
  • Do you by any chance have a code snipped available?

    Tuesday, February 5, 2013 4:47 PM
  • No. There should be examples on how to create a build logger in MSDN documentation. There is a working build logger (IDEBuildLogger if I remember correctly) here: http://mpfproj11.codeplex.com/
    Tuesday, February 5, 2013 4:51 PM
  • If you pass the project filename to your task a a required property, you can use it to find the currently executing project but it requires reflection to extract the info from the build engine.  As such, it's rather messy and is dependent on the version of MSBuild you are using so bear that in mind as future versions of MSBuild may change and cause the code to break.  Once you've got the project reference though, you can access it as usual to retrieve its properties and items.

    Here's an example that works in MSBuild 4.0: http://shfb.codeplex.com/SourceControl/changeset/view/101283#2015117

    Here's an example that works in MSBuild 2.0 and 3.5: http://shfb.codeplex.com/SourceControl/changeset/view/85384#1673590

    See the Execute() and GetCurrentProject()/GetCurrentProjectInstance() methods in each.

    I wasn't aware of the build logger approach and, if that is viable, it would probably be the better option in the long run as it wouldn't be dependent on the inner workings of the build engine.

    Eric

    Tuesday, February 5, 2013 8:37 PM
  • Actually, I like your approach better :). The build logger, while giving you a clean access through the public APIs, has to be specified before the build starts. You can do it via a command line option, but that's messy at best.
    Tuesday, February 5, 2013 8:51 PM
  • Thanks everyone it looks like I got my answer
    Tuesday, February 5, 2013 8:54 PM