Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
MSBuild-uppgifter skapas vanligtvis genom att kompilera en klass som implementerar ITask gränssnittet. Mer information finns i Uppgifter.
När du vill undvika kostnaderna för att skapa en kompilerad uppgift kan du skapa en infogad aktivitet i projektfilen eller i en importerad fil. Du behöver inte skapa en separat sammansättning som värd för uppgiften. Med hjälp av en infogad uppgift blir det enklare att hålla reda på källkoden och enklare att distribuera uppgiften. Källkoden är integrerad i MSBuild-projektfilen eller den importerade filen, vanligtvis en .targets fil.
Du skapar en infogad aktivitet med hjälp av en koduppgiftsfabrik. För aktuell utveckling bör du använda RoslynCodeTaskFactory, inte CodeTaskFactory.
CodeTaskFactory stöder endast C#-versioner upp till 4.0.
Infogade uppgifter är avsedda som en bekvämlighet för små uppgifter som inte kräver komplicerade beroenden. Felsökningsstöd för infogade uppgifter är begränsat. Vi rekommenderar att du skapar en kompilerad uppgift i stället för infogad aktivitet när du vill skriva mer komplex kod, referera till ett NuGet-paket, köra externa verktyg eller utföra åtgärder som kan skapa felvillkor. Dessutom kompileras infogade uppgifter varje gång du skapar, så det kan ha en märkbar inverkan på byggprestanda.
Strukturen för en infogad uppgift
En infogad aktivitet finns i ett UsingTask-element . Den infogade aktiviteten och elementet UsingTask som innehåller den ingår vanligtvis i en .targets fil och importeras till andra projektfiler efter behov. Här är en grundläggande infogad uppgift som inte gör något, men som illustrerar syntaxen:
<!-- 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>
Elementet UsingTask i exemplet har tre attribut som beskriver uppgiften och den infogade aktivitetsfabrik som kompilerar den.
Attributet
TaskNamenamnger uppgiften, i det här falletDoNothing.Attributet
TaskFactorynamnger klassen som implementerar den infogade aktivitetsfabriken.Attributet
AssemblyFileger platsen för den infogade aktivitetsfabriken. Du kan också användaAssemblyNameattributet för att ange det fullständigt kvalificerade namnet på den infogade aktivitetsfabriksklassen, som vanligtvis finns i$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll.
De återstående elementen i DoNothing aktiviteten är tomma och tillhandahålls för att illustrera ordningen och strukturen för en infogad aktivitet. Ett fullständigt exempel visas senare i den här artikeln.
Elementet
ParameterGroupär valfritt. När den anges deklareras parametrarna för aktiviteten. Mer information om indata- och utdataparametrar finns i Indata- och utdataparametrar senare i den här artikeln.Elementet
Taskbeskriver och innehåller aktivitetens källkod.Elementet
Referenceanger referenser till de .NET-sammansättningar som du använder i koden. Att använda det här elementet motsvarar att lägga till en referens till ett projekt i Visual Studio. AttributetIncludeanger sökvägen till den refererade sammansättningen. Sammansättningar i mscorlib, .NET Standard, Microsoft.Build.Framework och Microsoft.Build.Utilities.Core, samt vissa sammansättningar som transitivt refereras till som beroenden, är tillgängliga utanReference.Elementet
Usingvisar de namnområden som du vill komma åt. Det här elementet motsvararusingdirektivet i C#. AttributetNamespaceanger det namnområde som ska inkluderas. Det fungerar inte att placera ettusingdirektiv i den infogade koden, eftersom den koden placeras i en metodtext, därusingdirektiv inte tillåts.
Reference och Using element är språkagnostiska. Infogade uppgifter kan skrivas i Visual Basic eller C#.
Anmärkning
Element som ingår i elementet Task är specifika för aktivitetsfabriken, i det här fallet koduppgiftsfabriken.
Kodelement
Det sista underordnade elementet som visas i elementet Task är elementet Code . Elementet Code innehåller eller letar upp den kod som du vill kompilera till en uppgift. Vad du lägger till i elementet Code beror på hur du vill skriva uppgiften.
Attributet Language anger det språk där koden skrivs. Acceptabla värden är cs för C#, vb för Visual Basic.
Attributet Type anger vilken typ av kod som finns i elementet Code .
Om värdet
Typeför ärClassinnehåller elementetCodekod för en klass som härleds från ITask gränssnittet.Om värdet
Typeför ärMethoddefinierar koden en åsidosättning avExecute-metoden för ITask gränssnittet.Om värdet
Typeför ärFragmentdefinierar koden innehållet iExecutemetoden, men inte signaturen eller -instruktionenreturn.
Själva koden visas vanligtvis mellan en <![CDATA[ markör och en ]]> markör. Eftersom koden finns i ett CDATA-avsnitt behöver du inte bekymra dig om att undvika reserverade tecken, till exempel "<" eller ">".
Du kan också använda Source -attributet för -elementet Code för att ange platsen för en fil som innehåller koden för din uppgift. Koden i källfilen måste vara av den typ som anges av attributet Type . Om attributet Source finns är Classstandardvärdet Type för . Om Source inte finns är Fragmentstandardvärdet .
Anmärkning
När du definierar aktivitetsklassen i källfilen måste klassnamnet överensstämma med TaskName attributet för motsvarande UsingTask-element .
HelloWorld
Här är ett exempel på en enkel infogad uppgift. HelloWorld-aktiviteten visar "Hello, world!" på standardfelloggningsenheten, som vanligtvis är systemkonsolen eller Visual Studio-utdatafönstret .
<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>
Du kan spara HelloWorld-aktiviteten i en fil med namnet HelloWorld.targets och sedan anropa den från ett projekt på följande sätt.
<Project>
<Import Project="HelloWorld.targets" />
<Target Name="Hello">
<HelloWorld />
</Target>
</Project>
Indata- och utdataparametrar
Infogade aktivitetsparametrar är underordnade element i ett ParameterGroup element. Varje parameter tar namnet på det element som definierar det. Följande kod definierar parametern Text.
<ParameterGroup>
<Text />
</ParameterGroup>
Parametrar kan ha ett eller flera av följande attribut:
-
Requiredär ett valfritt attribut som ärfalsesom standard. Omtruekrävs parametern och måste anges ett värde innan aktiviteten anropas. -
ParameterTypeär ett valfritt attribut som ärSystem.Stringsom standard. Den kan anges till valfri fullständigt kvalificerad typ som antingen är ett objekt eller ett värde som kan konverteras till och från en sträng med hjälp ChangeTypeav . (Med andra ord alla typer som kan skickas till och från en extern uppgift.) -
Outputär ett valfritt attribut som ärfalsesom standard. Omtruemåste parametern ges ett värde innan den returneras från metoden Kör.
Ett exempel:
<ParameterGroup>
<Expression Required="true" />
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<Tally ParameterType="System.Int32" Output="true" />
</ParameterGroup>
definierar dessa tre parametrar:
Expressionär en obligatorisk indataparameter av typen System.String.Filesär en obligatorisk indataparameter för objektlistan.Tallyär en utdataparameter av typen System.Int32.
Om elementet Code har Type attributet Fragment eller Methodskapas egenskaperna automatiskt för varje parameter. Annars måste egenskaperna uttryckligen deklareras i uppgiftskällans kod och måste exakt matcha deras parameterdefinitioner.
Felsöka en infogad uppgift
MSBuild genererar en källfil den infogade uppgiften och skriver utdata till textfilen med ett GUID-filnamn i mappen temporära filer, AppData\Local\Temp\MSBuildTemp. Utdata tas normalt bort, men för att bevara den här utdatafilen kan du ange miljövariabeln MSBUILDLOGCODETASKFACTORYOUTPUT till 1.
Exempel 1
Följande infogade uppgift ersätter varje förekomst av en token i den angivna filen med det angivna värdet.
<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>
Exempel 2
Följande infogade uppgift genererar serialiserade utdata. Det här exemplet visar användningen av en utdataparameter och en referens.
<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>