none
Using DTE to set a custom build action

    Question

  • We use csproj files with a custom build action. In a VS package we add new files with a certain extension and want to assign our custom build action to the ProjectItem. Currently we try the following:

    Property prop = projItem.Properties.Item("BuildAction");
    prop.Value = someIntegerValue;

    There is an enum prjBuildAction providing the standard Build actions (None, Compile, Content, Embedded Resource). As far as I understand it, the custom build actions can be set using integer values > 3, the standard build actions using the values 0..3. But the values for custom build actions vary on differerent machines. They seem to be an index into a build actions list.

    The question is: How can I achieve the proper value for a custom build action like "MyTaskCompiler"? How can I access the build actions list to determine the right index?

    Thanks in advance for any idea.
    Mirko
    Friday, March 06, 2009 12:32 PM

Answers

  • Hi, Mirko

    I'm sorry that there is no a proper way to get the build actions list currently.  About the custom build action's value, I tried it, it exactly will changes on different machine, so I can only think of one method:  Dynamically modify the .csproj file after the new files were added , change the follow part in .csproj file:
    <Compile Include="MyFile.xxx">
          <SubType>Code</SubType>
    </Compile>

    To:
    <MyTaskCompiler Include="MyFile.xxx">
          <SubType>Code</SubType>
    </MyTaskCompiler>

    And then reload it.

    It sounds a little boring and there will be a warning dialog comes out(Reload the project file), so just an idea.

    Sincerely!
    Please mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Wesley Yao Thursday, March 12, 2009 2:16 AM
    Tuesday, March 10, 2009 10:41 AM
  • There is actually a way to change the BuildAction property in place instead of unloading/reloading the project file.

    My approach was to use a class that implements iWizard, and when an item was added, I used the ProjectItem that was passed into the ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem) method.

    If you change the 'ItemType' property of that projectItem to your custom one, it will change the BuildAction for you. (i.e. projectItem.Properties.Item("ItemType").Value = "MyOwnBuildActionChoice".

    Hope this helps!  Let me know if you have any other related questions.

    • Proposed as answer by Paul Reisert Thursday, June 25, 2009 11:34 PM
    • Marked as answer by Wesley Yao Friday, June 26, 2009 3:14 AM
    Thursday, June 25, 2009 11:34 PM

All replies

  • Saturday, March 07, 2009 2:16 AM
  • Hi, Mirko

    I'm sorry that there is no a proper way to get the build actions list currently.  About the custom build action's value, I tried it, it exactly will changes on different machine, so I can only think of one method:  Dynamically modify the .csproj file after the new files were added , change the follow part in .csproj file:
    <Compile Include="MyFile.xxx">
          <SubType>Code</SubType>
    </Compile>

    To:
    <MyTaskCompiler Include="MyFile.xxx">
          <SubType>Code</SubType>
    </MyTaskCompiler>

    And then reload it.

    It sounds a little boring and there will be a warning dialog comes out(Reload the project file), so just an idea.

    Sincerely!
    Please mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Wesley Yao Thursday, March 12, 2009 2:16 AM
    Tuesday, March 10, 2009 10:41 AM
  • Thanks for your answer. That's exactly the way we solved it for the moment.

    Regards
    Mirko
    Wednesday, March 11, 2009 1:41 PM
  • There is actually a way to change the BuildAction property in place instead of unloading/reloading the project file.

    My approach was to use a class that implements iWizard, and when an item was added, I used the ProjectItem that was passed into the ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem) method.

    If you change the 'ItemType' property of that projectItem to your custom one, it will change the BuildAction for you. (i.e. projectItem.Properties.Item("ItemType").Value = "MyOwnBuildActionChoice".

    Hope this helps!  Let me know if you have any other related questions.

    • Proposed as answer by Paul Reisert Thursday, June 25, 2009 11:34 PM
    • Marked as answer by Wesley Yao Friday, June 26, 2009 3:14 AM
    Thursday, June 25, 2009 11:34 PM
  • Thanks, Paul.  I also noticed that this attribute "ItemType" can do the job, please also take a look at this thread and give some advice if you have a better idea:
    How to set the Build Action for an item created by a Visual Studio item template?

    Thanks for your effort again.

    Wesley
    Please mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, June 26, 2009 3:14 AM
  • There is actually a way to change the BuildAction property in place instead of unloading/reloading the project file.

    My approach was to use a class that implements iWizard, and when an item was added, I used the ProjectItem that was passed into the ProjectItemFinishedGenerating(EnvDTE.ProjectItem projectItem) method.

    If you change the 'ItemType' property of that projectItem to your custom one, it will change the BuildAction for you. (i.e. projectItem.Properties.Item("ItemType").Value = "MyOwnBuildActionChoice".

    Hope this helps!  Let me know if you have any other related questions.

    Hi Paul, 

    I tried applying your suggestion about 'ItemType' but I failed and now I'm stuck.

    In my case I have a form file (xml) and four dependent files that my DesignerLoader generates. When I add a new form to the project all four dependent files are generated like this:

    DocData data = this._designerDocDataService.GetChildDocData(filename, access, tempFileName);
    // ...
    EnvDTE.ProjectItem item; 
    // ... find the item in the hierarchy ...
    // set build action
    item.Properties.Item("ItemType").Value = "Embedded Resource";
    
    So, I'm trying to set Build Action to Embedded Resource, and it actually says Embedded Resource when I look at the item properties in property grid, but unfortunately it is treated as a new value in the list so the file does not get embedded.



    Do you have any idea on how to accomplish this ?

    thanks for any input

    Saturday, March 13, 2010 11:06 PM
  • Hi Vladimir,

    I know this is late but I had the same issue as you, except I was setting the ItemType attribute in my Visual Studio Item Template.  When I set ItemType="Embedded Resource", I would get the same duplicate "Embedded Resource" build action as in your screenshot above.  However, when I removed the space and set ItemType="EmbeddedResource", it worked as expected.

    I suspect the same issue when setting the ItemType programmatically as you are trying to do.

    I hope this helps.

    Gerard

     

    Friday, March 04, 2011 9:14 PM
  • Hi Gerard,

    I'm no longer working on that project but thanks for your answer, it may come in handy in future for me, or someone else.
    After a lot of headache I fixed that issue at the time by using a slightly different approach:

    protected DocData GetDocData(string filename, FileAccess access, Nullable<VSLangProj.prjBuildAction> buildAction)
    {
    	// ...
    
    		// get project item from hierarchy 
    		_hierarchy.GetProperty(childItemId, (int)__VSHPROPID.VSHPROPID_ExtObject, out pvar);
    		EnvDTE.ProjectItem item = pvar as EnvDTE.ProjectItem;
    		// set item type
    		//item.Properties.Item("ItemType").Value = "Embedded Resource"; 
    		Property prop = item.Properties.Item("BuildAction");
    		if (prop != null)
    			prop.Value = buildAction;
    
    	// ...
    }
    

    passing prjBuildAction.prjBuildActionEmbeddedResource for buildAction.

    I'm not sure which approach is better, or if those enum values could be compromised by some other addins/packages installing their own BuildActions (common sense makes me think that those values are independent but you never know).

    Hopefully, future readers will be able to solve their problem using one or the other approach.

    Best regards,
    Vladimir

    • Proposed as answer by k_cire0426 Tuesday, October 23, 2012 1:16 AM
    Friday, March 04, 2011 10:51 PM
  • Thanks, work very well :)

    Thursday, July 18, 2013 7:23 PM