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
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.
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?