Our last post included a short quiz on property escaping, and hopefully you found it somewhat entertaining. Since the answers to when and how we escape can get rather lengthy, the answers to the quiz are split across two posts. Let’s get right into part one!
We escape this property because when the user types it in they expect that exact path to get used during the build process. If the path is, for example, “c:\my;directory;has;a;dumb;name” we really need to escape those semicolons so they don’t accidentally get treated as separators by MSBuild when OutputPath is passed in as a property to a task. You can see this in action by setting the OutputPath property to the sample I gave above. The resulting XML in the project file is:
This gets escaped for the same reason as the OutputPath. When it's saved by the project system it's the exact name of the assembly and any semicolons or other special characters would cause weird behaviour when passed into a task.
WarningLevel: Not Escaped
This is somewhat of a trick question. This property is only ever a single digit, so whether we escape is irrelevant. We like to err on the side of not escaping, however.
ReferencePath: Escaped, kinda sorta
This was definitely a trick question. For the example given yesterday you don't need any escaping:
c:\MyReferencePath ; c:\YourReferencePath
In this case the semi-colon is exactly what you want: it is a delimiter between two separate values stored in the property, and tasks will certainly want to see them as separate items in a list. What happens, though, when the paths look like this:
c:\this;is;a;stupid;path ; c:\this;is;also;a;stupid;path
Uh oh. Now we have a problem. That’s why I said we kinda sorta escape. We actually escape within each path, but we don’t escape the separators. You might think we have all sort of convoluted code to do this, but we don't. Remember, I said this was definitely a trick question [:)]. This is what the UI for setting the ReferencePath looks like in Visual Studio:
The UI actually asks the user for the items as individual paths, and can then have MSBuild escape them before stitching them all together into a single property to store in the project file. With this UI, the ReferencePath problem is effectively identical to OutputPath.
Come back tomorrow for answers to the rest of the quiz!
[ Author: Neil Enns ]