I am writing an inline task for MSBuild. It requires a reference to
The task works great if I hard-code the path to the System.ServiceProcess.dll file, like this:
<UsingTask TaskName="MyTask" TaskFactory="CodeTaskFactory" 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.
$(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
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
<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.
<Reference /> but not inside
Why does it happen for
$(FrameworkPathOverride) and not for
Why does it start happening to
$(MyPath) if it references
How can I avoid hard-coding this path?
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.
User contributions licensed under CC BY-SA 3.0