{"id":2043,"date":"2010-05-25T16:52:00","date_gmt":"2010-05-25T16:52:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudio\/2010\/05\/25\/programmatically-addingremovingquerying-vc-build-customizations\/"},"modified":"2022-10-13T14:30:06","modified_gmt":"2022-10-13T21:30:06","slug":"programmatically-addingremovingquerying-vc-build-customizations","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/programmatically-addingremovingquerying-vc-build-customizations\/","title":{"rendered":"Programmatically adding\/removing\/querying VC++ Build Customizations"},"content":{"rendered":"<div class=\"WordSection1\">\n<p class=\"MsoNormal\">Build Customizations (Custom Build Rules in earlier editions) are commonly used for invoking external tools that translate files from one format to the other, often resulting in C++ sources that can be compiled at the C++ compilation step. In this post, I will explain how to programmatically add, remove,\u00a0 and query for Build Customizations in a VC++ project. I will use the API exposed by the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms168475(v=VS.100).aspx\">Microsoft.VisualStudio.VCProjectEngine<\/a> namespace to achieve this goal. If you are creating wizards or project templates that introduce new file types which require custom processing during build, then you will find the contents of this post useful.<\/p>\n<p class=\"MsoNormal\">In VS2010, Build Customizations (BCs) are represented by 3 files \u2013 (1) an .xml file representing the schema information of the Rule and its properties, (2) a .props file contains default values of some\/all of these properties and (3) a .targets file that contains build logic and in addition, includes the .xml file. The .targets file is mandatory while the other two files are optional. VS2010 requires that all these three files have the same name and be present in the same location. See Li\u2019s <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/quick-help-on-vs2010-custom-build-rule\/\">blog post<\/a> for more details on BCs and their file format in VS2010.<\/p>\n<p class=\"MsoNormal\">For the purpose of this post, I will assume that you have a BC called MyBC which is represented by the three files MyBC.xml, MyBC.props and MyBC.targets in the \u201cC: BuildCustomizations\u201d directory as shown in the snapshot below.<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" style=\"max-height: 550px; max-width: 550px;\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/05\/3730.image001.png\" border=\"0\" \/><\/p>\n<p class=\"MsoNormal\">Adding a BC to a <span style=\"font-family: Consolas; color: #2b91af;\">VCProject<\/span> is a two-step process:<\/p>\n<p class=\"MsoListParagraphCxSpFirst\" style=\"text-indent: -.25in;\">1.<span style=\"font: 7pt 'Times New Roman';\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>First you need to get a <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas; color: #2b91af;\">VCToolFile<\/span> object for the BC by requesting the <span style=\"line-height: 115%; font-family: Consolas; color: #2b91af; font-size: 10pt;\">VCProjectEngine<\/span> (you can use the <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas;\">GetBuildCustomizationRepresentation()<\/span> method listed below for this purpose). A <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas; color: #2b91af;\">VCToolFile<\/span> object simply stores the BC name and location internally.<\/p>\n<p class=\"MsoListParagraphCxSpLast\" style=\"text-indent: -.25in;\">2.<span style=\"font: 7pt 'Times New Roman';\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>Add a BC represented by a <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas; color: #2b91af;\">VCToolFile<\/span> object to the <span style=\"font-family: Consolas; color: #2b91af;\">VCProject<\/span> (you can use the <span style=\"line-height: 115%; font-family: Consolas; font-size: 10pt;\">AddBuildCustomization()<\/span> method listed below for this purpose).<\/p>\n<p class=\"MsoNormal\">Below, I list the C# code for performing 4 operations \u2013 get representation for a BC from the <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas; color: #2b91af;\">VCProjectEngine<\/span> and add\/remove\/query(two varieties) a BC from a VC++ project. Personally, I prefer testing code involving VC++ API by first creating a dummy Visual Studio Package (you need to install the <a href=\"http:\/\/www.microsoft.com\/downloads\/details.aspx?familyid=47305CF4-2BEA-43C0-91CD-1B853602DCC5&amp;displaylang=en\">VS2010 SDK<\/a> to get the project template for this project type) and calling my test methods in the <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas;\">Initialize()<\/span> method. That is what <i>I<\/i> do, you should use whatever method you are most comfortable with.<\/p>\n<p class=\"MsoNormal\">To use the code below, you need to add reference to <span style=\"font-family: Consolas; color: blue;\">Microsoft.VisualStudio.VCProjectEngine.dll (Version 10) <\/span>and \u00a0add a <span style=\"font-family: Consolas; color: blue;\">using<\/span><span style=\"font-family: Consolas;\">\u00a0Microsoft.VisualStudio.VCProjectEngine; <\/span>statement in your code file. In the code, input parameter checking is not shown for brevity.<\/p>\n<p class=\"MsoNormal\"><b><span style=\"font-size: 14.0pt; line-height: 115%;\">Getting a representation object (<\/span><\/b><span style=\"font-size: 14.0pt; line-height: 115%; font-family: Consolas; color: #2b91af;\">VCToolFile<\/span><b><span style=\"line-height: 115%; font-size: 14pt;\">) for BC<\/span><\/b><\/p>\n<p class=\"MsoNormal\">You do this by calling <span style=\"font-family: Consolas; color: #2b91af;\">VCProjectEngine<\/span>.<span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas;\">LoadToolFile()<\/span>. This operation does not change state of the project system. You can call this operation any number of times, even with the same argument. In earlier editions of VS (2008 and prior), a BC was represented by a single .rules file and this method would actually parse that file. Hence the term \u201cload\u201d. However, in VS 2010, a BC is represented by up to three files and the actual parsing is done when you actually add the BC to a <span style=\"font-family: Consolas; color: #2b91af;\">VCProject<\/span>, not when you call the <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas;\">LoadToolFile <\/span>method.<\/p>\n<pre><span style=\"font-size: 9.0pt; font-family: Consolas; color: gray;\">\/\/\/<\/span><span style=\"font-family: Consolas; color: green; font-size: 9pt;\">\u00a0<\/span><span style=\"font-family: Consolas; color: gray; font-size: 9pt;\">&lt;summary&gt;<\/span><span style=\"font-family: Consolas; font-size: 9pt;\">\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0Gets\u00a0a\u00a0<\/span><span style=\"color: gray;\">&lt;see\u00a0cref=\"VCToolFile\"\/&gt;<\/span><span style=\"color: green;\">\u00a0object\u00a0that\u00a0stores\u00a0the\u00a0location\u00a0information\u00a0of<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0a\u00a0Build\u00a0Customization\u00a0(BC).<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;\/summary&gt;<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=\"targetsFileFullPath\"&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0full\u00a0path\u00a0for\u00a0the\u00a0BC\u00a0targets\u00a0file.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=\"engine\"&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0VCProjectEngine.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;returns&gt;<\/span><span style=\"color: green;\">\u00a0A\u00a0<\/span><span style=\"color: gray;\">&lt;see\u00a0cref=\"VCToolFile\"\/&gt;<\/span><span style=\"color: green;\">\u00a0object\u00a0corresponding\u00a0to\u00a0the\u00a0BC.\u00a0<\/span><span style=\"color: gray;\">&lt;\/returns&gt;<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;remarks&gt;<\/span><span style=\"color: green;\">\u00a0<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;para&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0.xml\u00a0and\u00a0.props\u00a0files\u00a0of\u00a0the\u00a0BC,\u00a0if\u00a0present,\u00a0must\u00a0have\u00a0the\u00a0same\u00a0name<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0and\u00a0be\u00a0present\u00a0in\u00a0the\u00a0same\u00a0directory\u00a0as\u00a0the\u00a0.targets\u00a0file.\u00a0<\/span><span style=\"color: gray;\">&lt;\/para&gt;<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;para&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0returned\u00a0<\/span><span style=\"color: gray;\">&lt;see\u00a0cref=\"VCToolFile\"\/&gt;<\/span><span style=\"color: green;\">\u00a0object\u00a0is\u00a0normally\u00a0used\u00a0to\u00a0add\u00a0this<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0BC\u00a0to\u00a0one\u00a0of\u00a0the\u00a0containing\u00a0VC++\u00a0projects.\u00a0<\/span><span style=\"color: gray;\">&lt;\/para&gt;<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;\/remarks&gt;<\/span>\r\n<span style=\"color: blue;\">private<\/span>\u00a0<span style=\"color: blue;\">static<\/span>\u00a0<span style=\"color: #2b91af;\">VCToolFile<\/span>\u00a0GetBuildCustomizationRepresentation(<span style=\"color: blue;\">string<\/span>\u00a0targetsFileFullPath,\u00a0<span style=\"color: #2b91af;\">VCProjectEngine<\/span>\u00a0engine)\r\n{\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0The\u00a0term\u00a0\"load\"\u00a0in\u00a0the\u00a0method\u00a0name\u00a0is\u00a0a\u00a0legacy\u00a0artifact;\u00a0none\u00a0of\u00a0the\u00a0BC\u00a0files\u00a0are\u00a0actually\u00a0loaded.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #2b91af;\">VCToolFile<\/span>\u00a0myBC\u00a0=\u00a0engine.LoadToolFile(targetsFileFullPath);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">return<\/span>\u00a0myBC;\r\n}<\/span><\/pre>\n<p class=\"MsoNormal\"><b><span style=\"font-size: 14.0pt; line-height: 115%;\">Adding\/Removing\/Querying for a BC from a <\/span><\/b><span style=\"font-size: 14.0pt; line-height: 115%; font-family: Consolas; color: #2b91af;\">VCProject<\/span><\/p>\n<p class=\"MsoNormal\">The following methods demonstrate how we can add, remove and query a BC from a <span style=\"font-family: Consolas; color: #2b91af;\">VCProject<\/span>. Note that both adding a BC that has already been added and removing a BC that has already been removed result in an Exception being thrown. I present two methods of query corresponding to two different types of query objects \u2013 one is the <span style=\"font-family: Consolas; color: #2b91af;\">VCToolFile<\/span> representation and another is the <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas; color: blue;\">string<\/span> object representing the targets file path.<\/p>\n<p class=\"MsoNormal\">Adding a BC to a <span style=\"font-family: Consolas; color: #2b91af;\">VCProject<\/span> using <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas;\">AddBuildCustomization()<\/span> is equivalent to performing the following action in UI: right-click the project node &gt; Build Customizations\u2026 &gt; check the BC entry (find it first, if necessary) and hit Ok.<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/05\/8877.image002.png\" border=\"0\" \/><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: 9.0pt; font-family: Consolas; color: gray;\">\/\/\/<\/span><span style=\"font-family: Consolas; color: green; font-size: 9pt;\">\u00a0<\/span><span style=\"font-family: Consolas; color: gray; font-size: 9pt;\">&lt;summary&gt;<\/span><span style=\"font-family: Consolas; font-size: 9pt;\">\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0Adds\u00a0a\u00a0Build\u00a0Customization\u00a0(BC)\u00a0to\u00a0a\u00a0VC++\u00a0project.<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;\/summary&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=&#8221;bc&#8221;&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0BC.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=&#8221;project&#8221;&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0VC++\u00a0project.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;remarks&gt;<\/span><span style=\"color: green;\">\u00a0<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;para&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0.xml\u00a0and\u00a0.props\u00a0files\u00a0of\u00a0the\u00a0BC,\u00a0if\u00a0present,\u00a0must\u00a0have\u00a0the\u00a0same\u00a0name<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0and\u00a0be\u00a0present\u00a0in\u00a0the\u00a0same\u00a0directory\u00a0as\u00a0the\u00a0.targets\u00a0file.\u00a0<\/span><span style=\"color: gray;\">&lt;\/para&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;para&gt;<\/span><span style=\"color: green;\">\u00a0You\u00a0need\u00a0to\u00a0first\u00a0get a representation of the BC by\u00a0first<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0calling\u00a0<\/span><span style=\"color: gray;\">&lt;see\u00a0cref=&#8221;GetBuildCustomizationRepresentation&#8221;\/&gt;<\/span><span style=\"color: green;\">\u00a0and\u00a0then\u00a0use\u00a0the<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0returned\u00a0object\u00a0as\u00a0the\u00a0argument\u00a0to\u00a0this\u00a0method.\u00a0<\/span><span style=\"color: gray;\">&lt;\/para&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;\/remarks&gt;<\/span>\n<span style=\"color: blue;\">private<\/span>\u00a0<span style=\"color: blue;\">static<\/span>\u00a0<span style=\"color: blue;\">void<\/span>\u00a0AddBuildCustomization(<span style=\"color: #2b91af;\">VCToolFile<\/span>\u00a0bc,\u00a0<span style=\"color: #2b91af;\">VCProject<\/span>\u00a0project)\n{\n<span style=\"color: green;\">\/\/\u00a0Add\u00a0the\u00a0BC\u00a0only\u00a0if\u00a0it\u00a0has\u00a0not\u00a0already\u00a0been\u00a0added.<\/span>\n<span style=\"color: blue;\">if<\/span>\u00a0(!BuildCustomizationExists(bc,\u00a0project))\n{\nproject.AddToolFile(bc);\n}\n}\u00a0<\/span><\/p>\n<p><span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;summary&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0Removes\u00a0a\u00a0Build\u00a0Customization\u00a0(BC)\u00a0from\u00a0a\u00a0VC++\u00a0project.<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;\/summary&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=&#8221;bc&#8221;&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0BC.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=&#8221;project&#8221;&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0VC++\u00a0project.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\n<span style=\"color: blue;\">private<\/span>\u00a0<span style=\"color: blue;\">static<\/span>\u00a0<span style=\"color: blue;\">void<\/span>\u00a0RemoveBuildCustomization(<span style=\"color: #2b91af;\">VCToolFile<\/span>\u00a0bc,\u00a0<span style=\"color: #2b91af;\">VCProject<\/span>\u00a0project)\n{\n<span style=\"color: green;\">\/\/\u00a0Remove\u00a0the\u00a0BC\u00a0only\u00a0if\u00a0it\u00a0has\u00a0been\u00a0added\u00a0before.<\/span>\n<span style=\"color: blue;\">if<\/span>\u00a0(BuildCustomizationExists(bc,\u00a0project))\n{\nproject.RemoveToolFile(bc);\n}\n}<\/p>\n<p><span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;summary&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0Checks\u00a0if\u00a0a\u00a0Build\u00a0Customization\u00a0(BC)\u00a0exists\u00a0in\u00a0a\u00a0VC++\u00a0project.<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;\/summary&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=&#8221;bc&#8221;&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0BC.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=&#8221;project&#8221;&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0VC++\u00a0project.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;returns&gt;<\/span><span style=\"color: green;\">\u00a0true,\u00a0if\u00a0the\u00a0BC\u00a0exists,\u00a0else\u00a0false.\u00a0<\/span><span style=\"color: gray;\">&lt;\/returns&gt;<\/span>\n<span style=\"color: blue;\">private<\/span>\u00a0<span style=\"color: blue;\">static<\/span>\u00a0<span style=\"color: blue;\">bool<\/span>\u00a0BuildCustomizationExists(<span style=\"color: #2b91af;\">VCToolFile<\/span>\u00a0bc,\u00a0<span style=\"color: #2b91af;\">VCProject<\/span>\u00a0project)\n{\n<span style=\"color: #2b91af;\">VCToolFile<\/span>\u00a0myBC\u00a0=\u00a0GetAddedBuildCustomization(bc.Path,\u00a0project);<\/p>\n<p><span style=\"color: blue;\">return<\/span>\u00a0(myBC\u00a0!=\u00a0<span style=\"color: blue;\">null<\/span>);\n}<\/p>\n<p><span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;summary&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0Returns\u00a0an\u00a0added\u00a0Build\u00a0Customization\u00a0(BC)\u00a0from\u00a0a\u00a0VC++\u00a0project.<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;\/summary&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=&#8221;targetsFileFullPath&#8221;&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0full\u00a0path\u00a0for\u00a0the\u00a0BC\u00a0targets\u00a0file.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=&#8221;project&#8221;&gt;<\/span><span style=\"color: green;\">\u00a0The\u00a0VC++\u00a0project.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;returns&gt;<\/span><span style=\"color: green;\">\u00a0A\u00a0<\/span><span style=\"color: gray;\">&lt;see\u00a0cref=&#8221;VCToolFile&#8221;\/&gt;<\/span><span style=\"color: green;\">\u00a0object\u00a0corresponding\u00a0to\u00a0the\u00a0BC,\u00a0if\u00a0it<\/span>\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0exists.\u00a0Else,\u00a0null.\u00a0<\/span><span style=\"color: gray;\">&lt;\/returns&gt;<\/span>\n<span style=\"color: blue;\">private<\/span>\u00a0<span style=\"color: blue;\">static<\/span>\u00a0<span style=\"color: #2b91af;\">VCToolFile<\/span>\u00a0GetAddedBuildCustomization(<span style=\"color: blue;\">string<\/span>\u00a0targetsFileFullPath,\u00a0<span style=\"color: #2b91af;\">VCProject<\/span>\u00a0project)\n{\n<span style=\"color: green;\">\/\/\u00a0Query\u00a0for\u00a0the\u00a0BC\u00a0by\u00a0using\u00a0its\u00a0full\u00a0path.<\/span>\n<span style=\"color: #2b91af;\">VCToolFile<\/span>\u00a0myBC\u00a0=\u00a0project.ToolFiles.Item(targetsFileFullPath);<\/p>\n<p><span style=\"color: blue;\">return<\/span>\u00a0myBC;\n}<\/p>\n<p class=\"MsoNormal\">Finally, I would like to list some driver code which I used to test the above methods.<\/p>\n<p class=\"MsoNormal\"><b><span style=\"font-size: 14.0pt; line-height: 115%;\">Test Driver<\/span><\/b><\/p>\n<p class=\"MsoNormal\">The below driver method invokes the above methods. Notice that I access the <span style=\"font-family: Consolas; color: #2b91af;\">VCProjectEngine<\/span> and <span style=\"font-family: Consolas; color: #2b91af;\">VCProject<\/span> objects using <a href=\"http:\/\/msdn.microsoft.com\/query\/dev10.query?appId=Dev10IDEF1&amp;l=EN-US&amp;k=k(ENVDTE.DTE);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&amp;rd=true\"><span style=\"line-height: 115%; font-family: Consolas; font-size: 10pt;\">DTE<\/span><\/a>. Since I wrote my driver in a Visual Studio Package, the <span style=\"font-size: 10.0pt; line-height: 115%; font-family: Consolas; color: #2b91af;\">DTE<\/span> object is easily available to me. You should, however, access the project engine and project objects in a way that is most meaningful in your context.<\/p>\n<pre><span style=\"font-size: 9.0pt; font-family: Consolas; color: gray;\">\/\/\/<\/span><span style=\"font-family: Consolas; color: green; font-size: 9pt;\">\u00a0<\/span><span style=\"font-family: Consolas; color: gray; font-size: 9pt;\">&lt;summary&gt;<\/span><span style=\"font-family: Consolas; font-size: 9pt;\">\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0Invokes\u00a0the\u00a0above\u00a0methods\u00a0to\u00a0test\u00a0them.<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;\/summary&gt;<\/span>\r\n<span style=\"color: gray;\">\/\/\/<\/span><span style=\"color: green;\">\u00a0<\/span><span style=\"color: gray;\">&lt;param\u00a0name=\"serviceProvider\"&gt;<\/span><span style=\"color: green;\">\u00a0A\u00a0Visual\u00a0Studio\u00a0service\u00a0provider.\u00a0<\/span><span style=\"color: gray;\">&lt;\/param&gt;<\/span>\r\n<span style=\"color: blue;\">internal<\/span>\u00a0<span style=\"color: blue;\">static<\/span>\u00a0<span style=\"color: blue;\">void<\/span>\u00a0TestDriver(<span style=\"color: #2b91af;\">IServiceProvider<\/span>\u00a0serviceProvider)\r\n{\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0Get\u00a0the\u00a0DTE\u00a0object\u00a0corresponding\u00a0to\u00a0the\u00a0VS\u00a0instance\u00a0this\u00a0code\u00a0is<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0running\u00a0in.\u00a0I\u00a0had\u00a0this\u00a0code\u00a0in\u00a0a\u00a0dummy\u00a0Visual\u00a0Studio\u00a0Package,\u00a0so<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0I\u00a0could\u00a0readily\u00a0access\u00a0the\u00a0VS\u00a0services\u00a0such\u00a0as\u00a0SDTE.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: #2b91af;\">DTE<\/span>\u00a0vsEnvironment\u00a0=\u00a0serviceProvider.GetService(<span style=\"color: blue;\">typeof<\/span>(<span style=\"color: #2b91af;\">SDTE<\/span>))\u00a0<span style=\"color: blue;\">as<\/span>\u00a0<span style=\"color: #2b91af;\">DTE<\/span>;\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0Get\u00a0the\u00a0first\u00a0project\u00a0in\u00a0the\u00a0solution\u00a0and\u00a0assume\u00a0that\u00a0it\u00a0is\u00a0a\u00a0VCProject.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0You\u00a0should\u00a0find\u00a0the\u00a0VCProject\u00a0you\u00a0are\u00a0interested\u00a0in\u00a0by\u00a0using\u00a0a\u00a0more<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0meaningful\u00a0approach.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: #2b91af;\">VCProject<\/span>\u00a0project\u00a0=\u00a0vsEnvironment.Solution.Projects.Item(1).Object\u00a0<span style=\"color: blue;\">as<\/span>\u00a0<span style=\"color: #2b91af;\">VCProject<\/span>;\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0Get\u00a0a\u00a0reference\u00a0to\u00a0the\u00a0VCProjectEngine.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: #2b91af;\">VCProjectEngine<\/span>\u00a0engine\u00a0=\u00a0project.VCProjectEngine;<\/span><\/pre>\n<pre><span style=\"font-family: Consolas; font-size: 9pt;\">\r\n \u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0The\u00a0full\u00a0path\u00a0of\u00a0the\u00a0BC .targets\u00a0file\u00a0we use in\u00a0this\u00a0blog\u00a0post.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">string<\/span>\u00a0targetsFileFullPath\u00a0=\u00a0<span style=\"color: #a31515;\">@\"C:BuildCustomizationsMyBC.targets\"<\/span>;\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0Get\u00a0a\u00a0representation\u00a0object\u00a0for\u00a0the\u00a0BC\u00a0by\u00a0requesting\u00a0the\u00a0VCProjectEngine.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: #2b91af;\">VCToolFile<\/span>\u00a0myBC\u00a0=\u00a0GetBuildCustomizationRepresentation(targetsFileFullPath,\u00a0engine);\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0Add\u00a0the\u00a0BC\u00a0to\u00a0the\u00a0VCProject.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0AddBuildCustomization(myBC,\u00a0project);\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0Both\u00a0\"exists\"\u00a0and\u00a0\"exists2\"\u00a0will\u00a0be\u00a0true.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">bool<\/span>\u00a0exists\u00a0=\u00a0BuildCustomizationExists(myBC,\u00a0project);\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: blue;\">bool<\/span>\u00a0exists2\u00a0=\u00a0(GetAddedBuildCustomization(targetsFileFullPath,\u00a0project)\u00a0!=\u00a0<span style=\"color: blue;\">null<\/span>);\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0Remove\u00a0the\u00a0BC\u00a0from\u00a0the\u00a0VCProject.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0RemoveBuildCustomization(myBC,\u00a0project);\r\n\u00a0\u00a0\u00a0\u00a0<span style=\"color: green;\">\/\/\u00a0Both\u00a0\"exists\"\u00a0and\u00a0\"exists2\"\u00a0will\u00a0be\u00a0false.<\/span>\r\n\u00a0\u00a0\u00a0\u00a0exists\u00a0=\u00a0BuildCustomizationExists(myBC,\u00a0project);\r\n\u00a0\u00a0\u00a0\u00a0exists2\u00a0=\u00a0(GetAddedBuildCustomization(targetsFileFullPath,\u00a0project)\u00a0!=\u00a0<span style=\"color: blue;\">null<\/span>);<\/span><\/pre>\n<pre><span style=\"font-family: Consolas; font-size: 9pt;\">}<\/span><span lang=\"EN\" style=\"font-family: 'Times New Roman','serif'; color: #333333; font-size: 12pt;\">\u00a0<\/span><\/pre>\n<pre class=\"\"><\/pre>\n<p class=\"MsoNormal\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/Pavan%20(2)_1.png\"><img decoding=\"async\" style=\"margin-left: 0px; margin-right: 0px; border-width: 0px;\" title=\"Pavan (2)\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/05\/Pavan202_thumb_1.png\" alt=\"Pavan (2)\" width=\"81\" height=\"83\" align=\"left\" border=\"0\" \/><\/a> <strong>Short Bio:<\/strong> <span style=\"font-size: small;\">Pavan Adharapurapu is a developer on the Visual Studio Project and Build team. <\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small;\"> As part of VS 2010, he has worked on numerous features of the VC++ project system such<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small;\"> as property sheets, filters, property pages, platform and tool extensibility, etc. His long term <\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small;\"> focus is on developing a &#8220;common project system&#8221; infrastructure which could be used to quickly<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small;\"> build richly featured project systems. Prior to joining the Visual Studio team in 2008, he was <\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small;\">working on Workflow technologies in Microsoft Dynamics Axapta. Pavan holds a Masters degree in Computer<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small;\">Science (CS) from the University of California, Los Angeles (UCLA) and a Bachelors degree in CS from the <\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small;\">Indian Institute of Technology (IIT), Madras. He lives in Redmond, WA with his wife and loves to play soccer<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-size: small;\">and watch movies in his spare time.<\/span><\/p>\n<p>&nbsp;<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Build Customizations (Custom Build Rules in earlier editions) are commonly used for invoking external tools that translate files from one format to the other, often resulting in C++ sources that can be compiled at the C++ compilation step. In this post, I will explain how to programmatically add, remove,\u00a0 and query for Build Customizations in [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":255385,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[155],"tags":[5,185],"class_list":["post-2043","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-studio","tag-csharp","tag-node-js"],"acf":[],"blog_post_summary":"<p>Build Customizations (Custom Build Rules in earlier editions) are commonly used for invoking external tools that translate files from one format to the other, often resulting in C++ sources that can be compiled at the C++ compilation step. In this post, I will explain how to programmatically add, remove,\u00a0 and query for Build Customizations in [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/2043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=2043"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/2043\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/255385"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=2043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=2043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=2043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}