Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az MSBuild-feladatok általában egy olyan osztály összeállításával jönnek létre, amely implementálja a ITask felületet. További információ: Feladatok.
Ha el szeretné kerülni a lefordított tevékenységek létrehozásának többletterhelését, létrehozhat egy tevékenységet beágyazottan a projektfájlban vagy egy importált fájlban. A feladat üzemeltetéséhez nem kell külön szerelvényt létrehoznia. A beágyazott feladatokkal könnyebben nyomon követheti a forráskódot, és egyszerűbbé válik a feladat üzembe helyezése. A forráskód integrálva van az MSBuild projektfájlba vagy importált fájlba, általában egy .targets fájlba.
Beágyazott feladatot kódfeladat-előállítóval hozhat létre. Az aktuális fejlesztéshez ne a RoslynCodeTaskFactoryt használja.CodeTaskFactory
CodeTaskFactory csak a 4.0-s verziójú C#-verziókat támogatja.
A beágyazott tevékenységek olyan kis feladatok kényelmét szolgálják, amelyek nem igényelnek bonyolult függőségeket. A beágyazott tevékenységek hibakeresési támogatása korlátozott. Ajánlott lefordított feladatot létrehozni beágyazott feladat helyett, ha összetettebb kódot szeretne írni, nuGet-csomagra hivatkozni, külső eszközöket futtatni, vagy olyan műveleteket végrehajtani, amelyek hibafeltételeket eredményezhetnek. A beágyazott feladatokat is minden buildeléskor lefordítja a rendszer, így észrevehető hatással lehet a build teljesítményére.
Beágyazott tevékenység felépítése
A beágyazott feladatokat egy UsingTask-elem tartalmazza. A beágyazott tevékenység és az UsingTask azt tartalmazó elem általában egy .targets fájlban van, és szükség szerint importálva van más projektfájlokba. Íme egy alapszintű beágyazott feladat, amely nem végez semmit, de a szintaxist szemlélteti:
<!-- This simple inline task does nothing. -->
<UsingTask
TaskName="DoNothing"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup />
<Task>
<Reference Include="" />
<Using Namespace="" />
<Code Type="Fragment" Language="cs">
</Code>
</Task>
</UsingTask>
A UsingTask példában szereplő elem három attribútummal rendelkezik, amelyek a feladatot és az azt fordító beágyazott feladat-előállítót írják le.
Ebben
TaskNameaz esetben az attribútum neve a tevékenység.DoNothingAz
TaskFactoryattribútum a beágyazott feladat-előállítót megvalósító osztálynak nevezi el.Az
AssemblyFileattribútum a beágyazott feladat-előállító helyét adja meg. Másik lehetőségként azAssemblyNameattribútum használatával megadhatja a beágyazott feladat-előállító osztály teljes nevét, amely általában a fájlban$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dlltalálható.
A tevékenység fennmaradó elemei DoNothing üresek, és a beágyazott tevékenységek sorrendjének és szerkezetének szemléltetésére szolgálnak. A cikk későbbi részében egy teljes példát mutatunk be.
Az
ParameterGroupelem nem kötelező. Ha meg van adva, deklarálja a tevékenység paramétereit. A bemeneti és kimeneti paraméterekkel kapcsolatos további információkért lásd a cikk későbbi , bemeneti és kimeneti paramétereit .Az
Taskelem leírja és tartalmazza a tevékenység forráskódját.Az
Referenceelem a kódban használt .NET-szerelvényekre mutató hivatkozásokat adja meg. Ennek az elemnek a használata egyenértékű azzal, ha a Visual Studióban egy projektre mutató hivatkozást ad hozzá. AzIncludeattribútum a hivatkozott szerelvény elérési útját adja meg. Az mscorlib, a .NET Standard, a Microsoft.Build.Framework és a Microsoft.Build.Utilities.Core szerelvények, valamint a függőségként tranzitív módon hivatkozott szerelvények nem érhetők elReference.Az
Usingelem felsorolja a elérni kívánt névtereket. Ez az elem egyenértékű ausingC# irányelvével. AzNamespaceattribútum megadja a belefoglalandó névteret. Nem működik irányelv elhelyezéseusinga beágyazott kódban, mert a kód egy metódustörzsbe kerül, aholusingaz irányelvek nem engedélyezettek.
Reference és Using az elemek nyelvi agnosztikusak. A beágyazott feladatok Visual Basic vagy C# nyelven is írhatók.
Megjegyzés:
Az elem által Task tartalmazott elemek a feladat-előállítóra, ebben az esetben a kód-feladat-előállítóra vonatkoznak.
Kódelem
Az elemen belül Task az utolsó gyermekelem az Code elem. Az Code elem tartalmazza vagy megkeresi a feladatba lefordítani kívánt kódot. Az elembe Code helyezett elemek attól függenek, hogyan szeretné megírni a feladatot.
Az Language attribútum azt a nyelvet határozza meg, amelyben a kód meg van írva. Az elfogadható értékek a cs C#, vb a Visual Basic esetében.
Az Type attribútum megadja az elemben Code található kód típusát.
Ha az érték
TypeazClass, akkor azCodeelem egy olyan osztály kódját tartalmazza, amely a ITask felületből származik.Ha az érték
TypeazMethod, akkor a kód a felület metódusánakExecutefelülbírálását ITask határozza meg.Ha az érték
TypeazFragment, akkor a kód határozza meg aExecutemetódus tartalmát, de az aláírást vagy az utasítástreturnnem.
Maga a kód általában egy jelölő és egy <![CDATA[]]> jelölő között jelenik meg. Mivel a kód egy CDATA-szakaszban található, nem kell aggódnia a fenntartott karakterek, például a "<" vagy a ">" elől.
Másik lehetőségként az Source elem attribútumával Code megadhatja a feladat kódját tartalmazó fájl helyét. A forrásfájl kódjának az attribútum által Type megadott típusnak kell lennie. Ha az Source attribútum jelen van, az alapértelmezett érték az TypeClass. Ha Source nincs jelen, az alapértelmezett érték a következő Fragment: .
Megjegyzés:
A feladatosztály forrásfájlban való definiálásakor az osztály nevének meg kell egyeznie a TaskName megfelelő UsingTask elem attribútumával.
HelloWorld
Íme egy példa egy egyszerű beágyazott feladatra. A HelloWorld feladat az alapértelmezett hibanaplózó eszközön jeleníti meg a "Hello, world!" szöveget, amely általában a rendszerkonzol vagy a Visual Studio Kimeneti ablaka.
<Project>
<!-- This simple inline task displays "Hello, world!" -->
<UsingTask
TaskName="HelloWorld"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup />
<Task>
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
// Display "Hello, world!"
Log.LogError("Hello, world!");
]]>
</Code>
</Task>
</UsingTask>
</Project>
A HelloWorld feladatot egy HelloWorld.targets nevű fájlba mentheti, majd meghívhatja egy projektből az alábbiak szerint.
<Project>
<Import Project="HelloWorld.targets" />
<Target Name="Hello">
<HelloWorld />
</Target>
</Project>
Bemeneti és kimeneti paraméterek
A beágyazott tevékenységparaméterek egy ParameterGroup elem gyermekelemei. Minden paraméter az azt meghatározó elem nevét veszi fel. A paramétert Textaz alábbi kód határozza meg.
<ParameterGroup>
<Text />
</ParameterGroup>
A paraméterek egy vagy több attribútummal rendelkezhetnek:
-
Requiredalapértelmezés szerint nem kötelező attribútumfalse. Hatrue, akkor a paraméter megadása kötelező, és a feladat meghívása előtt meg kell adni egy értéket. -
ParameterTypealapértelmezés szerint nem kötelező attribútumSystem.String. Bármilyen teljesen minősített típusra állítható be, amely egy elem vagy egy olyan érték, amely sztringgé alakítható a használatával ChangeType. (Más szóval minden olyan típus, amely átadható egy külső tevékenységnek, és amelyből át lehet adni.) -
Outputalapértelmezés szerint nem kötelező attribútumfalse. Hatrue, akkor a paraméternek meg kell adni egy értéket, mielőtt az Execute metódusból tér vissza.
Például
<ParameterGroup>
<Expression Required="true" />
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<Tally ParameterType="System.Int32" Output="true" />
</ParameterGroup>
a következő három paramétert határozza meg:
Expressiona System.String típusú kötelező bemeneti paraméter.Filesegy kötelező elemlista bemeneti paramétere.TallyEgy System.Int32 típusú kimeneti paraméter.
Ha az Code elem attribútuma TypeFragment vagy Method, akkor a rendszer minden paraméterhez automatikusan létrehozza a tulajdonságokat. Ellenkező esetben a tulajdonságokat explicit módon deklarálni kell a tevékenység forráskódjában, és pontosan meg kell egyezniük a paraméterdefiníciókkal.
Beágyazott feladat hibakeresése
Az MSBuild létrehoz egy forrásfájlt a beágyazott feladathoz, és a kimenetet egy GUID fájlnévvel írja a szövegfájlba az Ideiglenes fájlok mappában( AppData\Local\Temp\MSBuildTemp). A kimenet általában törlődik, de a kimeneti fájl megőrzése érdekében a környezeti változót MSBUILDLOGCODETASKFACTORYOUTPUT 1 értékre állíthatja.
1. példa
Az alábbi beágyazott feladat az adott fájlban lévő tokenek minden előfordulását lecseréli a megadott értékre.
<Project>
<UsingTask TaskName="TokenReplace" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Path ParameterType="System.String" Required="true" />
<Token ParameterType="System.String" Required="true" />
<Replacement ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs"><![CDATA[
string content = File.ReadAllText(Path);
content = content.Replace(Token, Replacement);
File.WriteAllText(Path, content);
]]></Code>
</Task>
</UsingTask>
<Target Name='Demo' >
<TokenReplace Path="Target.config" Token="$MyToken$" Replacement="MyValue"/>
</Target>
</Project>
2. példa
Az alábbi beágyazott feladat szerializált kimenetet hoz létre. Ez a példa egy kimeneti paraméter és egy hivatkozás használatát mutatja be.
<Project>
<PropertyGroup>
<RoslynCodeTaskFactoryAssembly Condition="$(RoslynCodeTaskFactoryAssembly) == ''">$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll</RoslynCodeTaskFactoryAssembly>
</PropertyGroup>
<UsingTask
TaskName="MyInlineTask"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(RoslynCodeTaskFactoryAssembly)">
<ParameterGroup>
<Input ParameterType="System.String" Required="true" />
<Output ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Reference Include="System.Text.Json" /> <!-- Reference an assembly -->
<Using Namespace="System.Text.Json" /> <!-- Use a namespace -->
<Code Type="Fragment" Language="cs">
<![CDATA[
Output = JsonSerializer.Serialize(new { Message = Input });
]]>
</Code>
</Task>
</UsingTask>
<Target Name="RunInlineTask">
<MyInlineTask Input="Hello, Roslyn!" >
<Output TaskParameter="Output" PropertyName="SerializedOutput" />
</MyInlineTask>
<Message Text="Serialized Output: $(SerializedOutput)" />
</Target>
</Project>