Zadania wbudowane programu MSBuild
Zadania programu MSBuild są zwykle tworzone przez kompilowanie klasy, która implementuje ITask interfejs. Aby uzyskać więcej informacji, zobacz Zadania.
Począwszy od programu .NET Framework w wersji 4, można tworzyć zadania wbudowane w pliku projektu. Nie trzeba tworzyć oddzielnego zestawu do hostowania zadania. Ułatwia to śledzenie kodu źródłowego i łatwiejsze wdrażanie zadania. Kod źródłowy jest zintegrowany ze skryptem.
W programie MSBuild 15.8 dodano element RoslynCodeTaskFactory . W przypadku bieżącego programowania należy użyć elementu RoslynCodeTaskFactory, a nie CodeTaskFactory. CodeTaskFactory obsługuje tylko wersje języka C# do wersji 4.0.
Struktura zadania wbudowanego
Wbudowane zadanie jest zawarte za pomocą elementu UsingTask . Wbudowane zadanie i UsingTask
element, który go zawiera, są zwykle uwzględniane w pliku .targets i importowane do innych plików projektu zgodnie z potrzebami. Oto podstawowe zadanie wbudowane. Zwróć uwagę, że nic nie robi.
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This simple inline task does nothing. -->
<UsingTask
TaskName="DoNothing"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup />
<Task>
<Reference Include="" />
<Using Namespace="" />
<Code Type="Fragment" Language="cs">
</Code>
</Task>
</UsingTask>
</Project>
Element UsingTask
w przykładzie ma trzy atrybuty opisujące zadanie i wbudowaną fabrykę zadań, która ją kompiluje.
Atrybut
TaskName
nazywa zadanie , w tym przypadkuDoNothing
.Atrybuty
TaskFactory
nazwiją klasę, która implementuje fabrykę zadań wbudowanych.Atrybut
AssemblyFile
udostępnia lokalizację wbudowanej fabryki zadań. Alternatywnie można użyć atrybutuAssemblyName
, aby określić w pełni kwalifikowaną nazwę wbudowanej klasy fabryki zadań, która zazwyczaj znajduje się w$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll
.
Pozostałe elementy DoNothing
zadania są puste i są udostępniane w celu zilustrowania kolejności i struktury zadania wbudowanego. Bardziej niezawodny przykład zostanie przedstawiony w dalszej części tego tematu.
Element
ParameterGroup
jest opcjonalny. Gdy zostanie określony, deklaruje parametry zadania. Aby uzyskać więcej informacji na temat parametrów wejściowych i wyjściowych, zobacz Parametry wejściowe i wyjściowe w dalszej części tego tematu.Element
Task
opisuje i zawiera kod źródłowy zadania.Element
Reference
określa odwołania do zestawów .NET używanych w kodzie. Jest to odpowiednik dodawania odwołania do projektu w programie Visual Studio. AtrybutInclude
określa ścieżkę przywołytowanego zestawu.Element
Using
zawiera listę przestrzeni nazw, do których chcesz uzyskać dostęp. Przypomina to instrukcjęUsing
w języku Visual C#. AtrybutNamespace
określa przestrzeń nazw do uwzględnienia.
Reference
i Using
elementy są niezależne od języka. Zadania wbudowane można napisać w jednym z obsługiwanych języków .NET CodeDom, na przykład Visual Basic lub Visual C#.
Uwaga
Elementy zawarte przez Task
element są specyficzne dla fabryki zadań, w tym przypadku fabryki zadań kodu.
Element kodu
Ostatnim elementem podrzędnym Task
, który ma pojawić się w elemecie , jest Code
element . Element Code
zawiera lub lokalizuje kod, który chcesz skompilować w zadaniu. To, co umieścisz w elemenie Code
, zależy od tego, jak chcesz napisać zadanie.
Atrybut Language
określa język, w którym jest napisany kod. Dopuszczalne wartości to cs
C#, vb
dla języka Visual Basic.
Atrybut Type
określa typ kodu, który znajduje się w elemecie Code
.
Jeśli wartość
Type
toClass
,Code
element zawiera kod klasy pochodzącej z interfejsu ITask .Jeśli wartość
Type
toMethod
, kod definiuje przesłonięćExecute
metodę interfejsu ITask .Jeśli wartość
Type
toFragment
, kod definiuje zawartośćExecute
metody, ale nie podpis lub instrukcjęreturn
.
Sam kod zwykle pojawia się między znacznikiem <![CDATA[
a znacznikiem ]]>
. Ponieważ kod znajduje się w sekcji CDATA, nie musisz martwić się o ucieczkę zastrzeżonych znaków, na przykład "<" lub ">".
Alternatywnie możesz użyć Source
atrybutu Code
elementu, aby określić lokalizację pliku zawierającego kod zadania. Kod w pliku źródłowym musi być typu określony przez Type
atrybut . Source
Jeśli atrybut jest obecny, wartość domyślna to Type
Class
. Jeśli Source
nie ma wartości, wartość domyślna to Fragment
.
Uwaga
Podczas definiowania klasy zadań w pliku źródłowym nazwa klasy musi być zgodna z atrybutem TaskName
odpowiedniego elementu UsingTask .
Helloworld
Oto bardziej niezawodne zadanie wbudowane. Zadanie HelloWorld wyświetla komunikat "Hello, world!" na domyślnym urządzeniu rejestrowania błędów, które jest zazwyczaj konsolą systemową lub oknem danych wyjściowych programu Visual Studio. Element Reference
w przykładzie jest dołączany tylko do ilustracji.
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This simple inline task displays "Hello, world!" -->
<UsingTask
TaskName="HelloWorld"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup />
<Task>
<Reference Include="System.Xml"/>
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
// Display "Hello, world!"
Log.LogError("Hello, world!");
]]>
</Code>
</Task>
</UsingTask>
</Project>
Zadanie HelloWorld można zapisać w pliku o nazwie HelloWorld.targets, a następnie wywołać je z projektu w następujący sposób.
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="HelloWorld.targets" />
<Target Name="Hello">
<HelloWorld />
</Target>
</Project>
Parametry wejściowe i wyjściowe
Wbudowane parametry zadania to elementy podrzędne ParameterGroup
elementu. Każdy parametr przyjmuje nazwę elementu, który go definiuje. Poniższy kod definiuje parametr Text
.
<ParameterGroup>
<Text />
</ParameterGroup>
Parametry mogą mieć co najmniej jeden z następujących atrybutów:
Required
jest opcjonalnym atrybutem, który jestfalse
domyślnie. Jeślitrue
parametr jest wymagany i musi mieć wartość przed wywołaniem zadania.ParameterType
jest opcjonalnym atrybutem, który jestSystem.String
domyślnie. Można go ustawić na dowolny w pełni kwalifikowany typ, który jest elementem lub wartością, którą można przekonwertować na i z ciągu przy użyciu elementu System.Convert.ChangeType. (Innymi słowy, dowolny typ, który można przekazać do i z zadania zewnętrznego).Output
jest opcjonalnym atrybutem, który jestfalse
domyślnie. Jeślitrue
parametr , należy podać wartość przed zwróceniem z metody Execute.
Przykład:
<ParameterGroup>
<Expression Required="true" />
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<Tally ParameterType="System.Int32" Output="true" />
</ParameterGroup>
definiuje następujące trzy parametry:
Expression
jest wymaganym parametrem wejściowym typu System.String.Files
jest wymaganym parametrem wejściowym listy elementów.Tally
jest parametrem wyjściowym typu System.Int32.
Code
Jeśli element ma Type
atrybut Fragment
lub Method
, właściwości są tworzone automatycznie dla każdego parametru. W przeciwnym razie właściwości muszą być jawnie zadeklarowane w kodzie źródłowym zadania i muszą dokładnie odpowiadać ich definicjom parametrów.
Przykład
Następujące zadanie wbudowane zastępuje każde wystąpienie tokenu w danym pliku daną wartością.
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="15.0">
<UsingTask TaskName="TokenReplace" TaskFactory="CodeTaskFactory" 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="C:\Project\Target.config" Token="$MyToken$" Replacement="MyValue"/>
</Target>
</Project>