# MSBuild inline task reference is escaping parenthesis, sometimes

6

I am writing an inline task for MSBuild. It requires a reference to System.ServiceProcess.dll.

The task works great if I hard-code the path to the System.ServiceProcess.dll file, like this:

<UsingTask
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"> <Task> <Reference Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.ServiceProcess.dll" /> <Code Type="Fragment" Language="cs">...working fine...</Code> </Task> </UsingTask>  However, I would rather not hard-code that path. If I just use <Reference Include="System.ServiceProcess.dll" />, I get an error: MSB3755: Could not find reference "System.ServiceProcess.dll", so I think I have to use the full path here. The $(FrameworkPathOverride) property contains the correct path already, so I tried to use that:

<Reference Include="$(FrameworkPathOverride)\System.ServiceProcess.dll" />  But that gives me an error: C:\path\to\project.csproj(93,3): error MSB3754: The reference assembly "C:\Program Files %28x86%29\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.ServiceProcess.dll" is invalid. "The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)"[C:\path\to\project.csproj] Notice how it escaped (x86) into %28x86%29. Notably, it seems to do this only for $(FrameworkPathOverride). If I define my own property and use it instead, it works just fine, unless that property also references $(FrameworkPathOverride). In other words, this works (but still has me hard-coding the path): <PropertyGroup> <MyPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5</MyPath> </PropertyGroup> // (later, inside <Task />) <References Include="$(MyPath)\System.ServiceProcess.dll" />


However, this fails with the same error that reports searching a path for %28x86%29:

<PropertyGroup>
<MyPath>$(FrameworkPathOverride)</MyPath> </PropertyGroup>  Just for kicks, I also tried this variation, which also fails with the same error: <PropertyGroup> <MyPath>$([System.Convert]::ToString("$(FrameworkPathOverride)"))</MyPath> </PropertyGroup>  Also, in all cases, the output of <Message Text="$(FrameworkPathOverride)" /> and <Message Test="$(MyPath)" /> are identical. The <Message /> task is not escaping the parenthesis inside $(FrameworkPathOverride), but the <Reference Include="..." /> is. Hmm.

Why does (x86) become %28x86%29 inside <Reference /> but not inside <Message />?

Why does it happen for $(FrameworkPathOverride) and not for $(MyPath)?

Why does it start happening to $(MyPath) if it references $(FrameworkPathOverride)?

How can I avoid hard-coding this path?

msbuild
msbuild-4.0
asked on Stack Overflow Jun 12, 2013 by Chris Nielsen

5

Similar to your last attempt, have you tried the following using the "Unescape" MSBuild Property Function?

<PropertyGroup>
<MyPath>$([MSBuild]::Unescape("$(FrameworkPathOverride)"))</MyPath>
</PropertyGroup>


It seems to be a known issue titled "MSBuild 4.0 UsingTask cannot have a path with parentheses": http://connect.microsoft.com/VisualStudio/feedback/details/532677/msbuild-4-0-usingtask-cannot-have-a-path-with-parentheses

Unfortunately, I have not had the opportunity to test this.