{"action":"created","issue":{"url":"https://api.github.com/repos/Excel-DNA/ExcelDna/issues/27","labels_url":"https://api.github.com/repos/Excel-DNA/ExcelDna/issues/27/labels{/name}","comments_url":"https://api.github.com/repos/Excel-DNA/ExcelDna/issues/27/comments","events_url":"https://api.github.com/repos/Excel-DNA/ExcelDna/issues/27/events","html_url":"https://github.com/Excel-DNA/ExcelDna/pull/27","id":104625751,"number":27,"title":"Replace post-build events with MSBuild targets + improvements","user":{"login":"CaioProiete","id":177608,"avatar_url":"https://avatars.githubusercontent.com/u/177608?v=3","gravatar_id":"","url":"https://api.github.com/users/CaioProiete","html_url":"https://github.com/CaioProiete","followers_url":"https://api.github.com/users/CaioProiete/followers","following_url":"https://api.github.com/users/CaioProiete/following{/other_user}","gists_url":"https://api.github.com/users/CaioProiete/gists{/gist_id}","starred_url":"https://api.github.com/users/CaioProiete/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CaioProiete/subscriptions","organizations_url":"https://api.github.com/users/CaioProiete/orgs","repos_url":"https://api.github.com/users/CaioProiete/repos","events_url":"https://api.github.com/users/CaioProiete/events{/privacy}","received_events_url":"https://api.github.com/users/CaioProiete/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-09-03T05:41:16Z","updated_at":"2015-09-03T09:36:40Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/Excel-DNA/ExcelDna/pulls/27","html_url":"https://github.com/Excel-DNA/ExcelDna/pull/27","diff_url":"https://github.com/Excel-DNA/ExcelDna/pull/27.diff","patch_url":"https://github.com/Excel-DNA/ExcelDna/pull/27.patch"},"body":"Hi Govert, so here it goes the PR as promised.\r\n\r\nOn this PR I tried to focus on fixing #17 and whilst I was at it, I've added a few improvements that I thought would make sense, and ended up fixing #16 as well. This PR also opens the door for #15, #18 and #19.\r\n\r\n\r\n### What does it do / How it works\r\nThis PR adds two new files to the NuGet package:\r\n\r\n\r\n#### tools\\ExcelDna.targets\r\nThis is a vanilla MSBuild project file that contains all the logic to replace what currently is done via post-build events. A link to import this file gets added to the `.csproj` / `.vbproj` / `.fsproj`, etc. so it gets loaded together with the project.\r\n\r\nMSBuild files are quite verbose in general, but the code is pretty straightforward and does what used to be in the post-build events (and more things which I explain later in this document):\r\n\r\n  * Copy the -AddIn.dna file to the output folder\r\n  * Copy the 32-bit .xll, with the same name as the -AddIn.dna, to the output folder\r\n  * Run ExcelDnaPack for the -AddIn.dna file\r\n  * Copy the -AddIn.dna file to a new file -AddIn64.dna to the output folder\r\n  * Copy the 64-bit .xll, with the same name as the -AddIn64.dna, to the output folder\r\n  * Run ExcelDnaPack for the -AddIn64.dna file\r\n\r\nAmong other things, this MSBuild file has a target called \"ExcelDnaBuild\" which hooks in to the AfterBuild event and therefore is is triggered every time a project is built, keeping a similar behavior as it is in v0.32.\r\n\r\nThe developer is not expected to edit or interface with the `ExcelDna.targets` file. It lives inside the nuget package folder, and gets replaced every time the NuGet package gets updated.\r\n\r\n\r\n#### content\\ExcelDna.props\r\nThis is another vanilla MSBuild project that gets added to the VS project and allows the developer to customize the default behavior of the ExcelDna build process.\r\n\r\nThis seemed a good way to give back some control/flexibility to the developer, now that the post-events are gone. So it is possible to configure things like:\r\n\r\n* Enable / Disable processing of platform-specific .dna files (e.g. don't build 32-bit files)\r\n* Enable / Disable generation of platform-specific .dna files (e.g. don't generate 64-bit files)\r\n* Enable / Disable packing of .dna files\r\n\r\nSo in other words, the `ExcelDna.targets` define a number of defaults, which match the current behavior of v0.32, and the `ExcelDna.props` allows the developer to override pretty much every aspect of it, if he/she wants to. The file that gets added is just a template with the variables that I think will be more commonly changed, but a more advanced developer can extend it to override almost every variable in the `.targets` file and also has the opportunity to hook into the build process to execute custom steps.\r\n\r\nSo, in summary, `ExcelDna.props` is there for the developer to edit it as he/she see fit. But if it gets renamed or deleted from the project, it's perfectly fine and the default values defined in the `ExcenDna.targets` will be used (which, again, match current v0.32 behavior).\r\n\r\n\r\n\r\n### Improvements / New Features\r\nBeing able to hook into the MSBuild pipeline gave me the chance to make some improvements that I find useful, and maybe others will do too.\r\n\r\n\r\n### Clean Solution\r\nI've introduced a target that hooks into the \"Clean Solution\" target (which also fires on Rebuild by default) which will delete any .dna, .xll, or .xll.config files in the output folder (e.g. `bin\\Debug`).\r\n\r\n\r\n#### Build Configuration File\r\nAs mentioned above, this adds a file called `ExcelDna.props` to the project that allows the developer to turn on/off certain steps of the build process. These parameters can also be overridden via the MSBuild command-line.\r\n\r\nThis is useful, for example, if during development you only care about building 64-bit versions of the add-in without packing, but then in the build server you want to build both 32-bit and 64-bit versions and pack them all.\r\n\r\n\r\n#### Support for multiple .dna files in the same project\r\nThe build target discovers any .dna file that exists in the project (including sub-folders) and automatically copies them to the output folder.\r\n\r\nIt also detects (based on conventions) what is the platform of the .dna file (e.g. 32-bit - `MyAddIn.dna`) and generates the corresponding version (e.g. 64-bit - `MyAddIn64.dna`). It also works the other way around (e.g. if you only have a file called `MyAddIn64.dna`, it will generate a `MyAddIn32.dna`). All of this is configurable via `ExcelDna.props`, so you can disable the automatic generation of any of these.\r\n\r\nThe build target also honors any folder structure you may have in the project, so if you have .dna files in sub-folders, they will be copied to the output directory using the same structure, as you'd expect.\r\n\r\n\r\n#### Support for custom platform-specific files\r\nThere are cases where the the 32-bit .dna file and the 64-bit .dna file need to reference different assemblies, therefore automatic generation is not an option. So if the project has a single file called `MyAddIn.dna`, it understands that this is a 32-bit file and (by default) will generate a `MyAddIn64.dna` file by making a copy of the 32-bit version.\r\n\r\nHowever, if the project has two files `MyOtherAddIn.dna` and `MyOtherAddIn64.dna`, the build target will respect that and will not overwrite either of these files with a copy from another one. It will use the files exactly as they are in the project.\r\n\r\n\r\n#### Support for any naming convention\r\nBecause all .dna files as discovered dynamically, the files don't have to be `ProjectName-AddIn.dna` and a developer call it anything (e.g. `MyAwesomeXLApp.dna`). The only important part is the suffix of the file, which determines the platform (e.g. `MyAwesomeXLApp.dna` = 32-bit, `MyAwesomeXLApp64.dna` = 64-bit).\r\n\r\nThe suffix is also configurable via ExcelDna.props, so a developer can use whatever suffix he/she wants (e.g. `MyAwesomeXLApp-x86.dna` = 32-bit, `MyAwesomeXLApp-x64.dna` = 64-bit).\r\n\r\n\r\n#### Support for App.config files (specific or generic) - if any exist\r\nThe build target will try to discover the most appropriate App.config file in the project and will copy it to the output folder, renaming it to match the corresponding .xll file.\r\n\r\nSome examples:\r\n* If the only config file in the project is called `App.config`, then any add-in will get a copy of it\r\n```\r\nApp.config => MyAddIn.xll.config\r\nApp.config => MyAddIn64.xll.config\r\n```\r\n\r\n* If there are specific files `MyAddIn.config` and `MyAddIn64.config`, then it will use that instead (even if an App.config exists)\r\n```\r\nMyAddIn.config => MyAddIn.xll.config\r\nMyAddIn64.config => MyAddIn64.xll.config\r\n``` \r\n\r\n* Also, if you have .dna files in sub-folders, it will give priority to the `App.config` that is in the same folder as the .dna file, and then fallback to the root folder of the project to use the `App.config` there, if exists.\r\n\r\n\r\n### Breaking Changes\r\nHopefully none.\r\n\r\nI tried very hard to keep the existing behavior and default settings, and my tests show that upgrading add-ins from v0.32 to this new version works exactly the same way for C#, VB .NET, and F# projects (I've tested with VS2010 from .NET 2.0 to .NET 4.0 and VS2013, from .NET 2.0 to .NET 4.5.1).\r\n\r\n\r\n### Changes in the original Powershell scripts\r\n\r\n#### Install.ps1\r\n\r\n* (Obviously) Removed the code that sets the post-build event commands\r\n\r\n* Removed the code that sets the `CopyToOutputDirectory` and  `BuildAction`, because it is not needed anymore. The MSBuild target now discovers .dna files in the project that have `BuildAction` `None` or `Content`\r\n\r\n\r\n#### Uninstall.ps1\r\n\r\n* (Obviously) Removed the code that cleaned the post-build event commands (no more desserts, banana, etc. sorry :))\r\n\r\n* Also removed the code that sets the `CopyToOutputDirectory` and `BuildAction` for the same reason above in Install.ps1\r\n\r\n\r\n### Next steps\r\nHopefully this is in the right direction and you will take it for a spin - and hopefully not find major bugs.\r\n\r\nI'd like to get this PR merged, and then start working on #15 which I believe will allow me to simplify the `.targets` a lot - you see, in this PR I'm using only native MSBuild tasks which makes things more difficult for simple things like loops and merge of collections as you can see in the code. My idea with #15 would be to create a custom MSBuild task for doing the version change and packing, and I can take the opportunity to create some other useful tasks that will simplify the MSBuild code.\r\n\r\nLooking forward to get your feedback.\r\n\r\nThanks,\r\nCaio Proiete\r\n\r\nps: This PR works better if you merge #25, but it is not required for you to test and validate that it is doing what you'd expect."},"comment":{"url":"https://api.github.com/repos/Excel-DNA/ExcelDna/issues/comments/137391882","html_url":"https://github.com/Excel-DNA/ExcelDna/pull/27#issuecomment-137391882","issue_url":"https://api.github.com/repos/Excel-DNA/ExcelDna/issues/27","id":137391882,"user":{"login":"govert","id":414659,"avatar_url":"https://avatars.githubusercontent.com/u/414659?v=3","gravatar_id":"","url":"https://api.github.com/users/govert","html_url":"https://github.com/govert","followers_url":"https://api.github.com/users/govert/followers","following_url":"https://api.github.com/users/govert/following{/other_user}","gists_url":"https://api.github.com/users/govert/gists{/gist_id}","starred_url":"https://api.github.com/users/govert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/govert/subscriptions","organizations_url":"https://api.github.com/users/govert/orgs","repos_url":"https://api.github.com/users/govert/repos","events_url":"https://api.github.com/users/govert/events{/privacy}","received_events_url":"https://api.github.com/users/govert/received_events","type":"User","site_admin":false},"created_at":"2015-09-03T09:36:40Z","updated_at":"2015-09-03T09:36:40Z","body":"That looks awesome! I'll have a closer look and try to figure out how to deal with the branching."}}