2013-06-12 21 views
6

Sto scrivendo un'attività inline per MSBuild. Richiede un riferimento a System.ServiceProcess.dll.MSBuild riferimento attività in linea è parentesi di escape, a volte

Il compito grandi opere se hard-code il percorso del file System.ServiceProcess.dll, in questo modo:

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

Tuttavia, avrei preferito non hard-code quel percorso.

Se utilizzo solo <Reference Include="System.ServiceProcess.dll" />, viene visualizzato un messaggio di errore: MSB3755: Could not find reference "System.ServiceProcess.dll", quindi penso di dover utilizzare il percorso completo qui.

La proprietà $(FrameworkPathOverride) contiene il percorso corretto già, così ho cercato di usare quella:

<Reference Include="$(FrameworkPathOverride)\System.ServiceProcess.dll" /> 

Ma che mi dà un errore:

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]

Notate come è sfuggito (x86) in %28x86%29.

In particolare, sembra farlo solo per $(FrameworkPathOverride). Se definisco la mia proprietà e la uso invece, funziona perfettamente, a meno che la proprietà non faccia riferimento anche a $(FrameworkPathOverride). In altre parole, questo funziona (ma ha ancora me hard-codifica il percorso):

<PropertyGroup> 
    <MyPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5</MyPath> 
</PropertyGroup> 

// (later, inside <Task />) 
<References Include="$(MyPath)\System.ServiceProcess.dll" /> 

Tuttavia, questo non funziona con lo stesso errore che i rapporti a cercare un percorso per %28x86%29:

<PropertyGroup> 
    <MyPath>$(FrameworkPathOverride)</MyPath> 
</PropertyGroup> 

Solo per calci, ho provato anche questa variante, che non riesce anche con lo stesso errore:

<PropertyGroup> 
    <MyPath>$([System.Convert]::ToString("$(FrameworkPathOverride)"))</MyPath> 
</PropertyGroup> 

inoltre, in tutti i casi, l'uscita del <Message Text="$(FrameworkPathOverride)" /> e <Message Test="$(MyPath)" /> sono identici. L'attività <Message /> è non fuori dalla parentesi all'interno di $(FrameworkPathOverride), ma lo <Reference Include="..." />è. Hmm.

Perché lo (x86) diventa all'interno di <Reference /> ma non all'interno di <Message />?

Perché succede per $(FrameworkPathOverride) e non per $(MyPath)?

Perché inizia a verificarsi a $(MyPath) se fa riferimento a $(FrameworkPathOverride)?

Come è possibile evitare di codificare manualmente questo percorso?

+0

non riesco a ottenere anche un percorso hard-coded per lavorare ce l'ho come' < Riferimento Include = "$ (SolutionDir) ImageTextWriter \ bin \ $ (Configuration) \ ImageTextWriter.dll" /> 'nella mia attività, ma la costruzione del progetto mi dice sempre che non riesce a trovare il file. Qualche idea? – dotNET

risposta

5

Simile al tuo ultimo tentativo, hai provato quanto segue utilizzando la funzione di proprietà MSBuild "Unescape"?

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

Sembra essere un problema noto denominato "MSBuild 4.0 UsingTask non può avere un percorso con parentesi ":.. http://connect.microsoft.com/VisualStudio/feedback/details/532677/msbuild-4-0-usingtask-cannot-have-a-path-with-parentheses

Purtroppo, non ho avuto la possibilità di provare questo

+1

Grazie, ha funzionato! –

+1

Ho avuto un problema simile e l'ho risolto con [MSBuild] :: Unescape anche. – Michael12345