Capitolo 2: Creazione di un'applicazione "Longhorn"
Introduzione
Capitolo 1: Modello di applicazione "Longhorn"
Capitolo 2: Creazione di un'applicazione "Longhorn"
Rettore di Brent
Wise Owl Consulting
Novembre 2003
Contenuto
Motore di compilazione Microsoft .NET: MSBuild.exe
Compilazione di Hello World con MSBuild
Terminologia di MSBuild
Compilazione di un'applicazione eseguibile Longhorn
Creazione di un assembly della libreria Longhorn
Compilazione di un documento longhorn
Un file XAML come dichiarazione di classe
Manifesto dell'applicazione
Manifesto della distribuzione
Esecuzione dell'applicazione
Perché creare un altro sistema di compilazione?
Sommario
Per compilare un'applicazione Longhorn, è necessario installare Longhorn Software Development Kit (SDK). In alternativa, è possibile installare una versione di Microsoft® Visual Studio® che supporta Longhorn. In questo libro non viene illustrato l'uso di Visual Studio perché le procedure guidate, le funzionalità di generazione di codice fantasia e le funzionalità di compilazione del progetto oscurano ciò che accade effettivamente sotto le quinte. Credo che dovresti capire cosa fa uno strumento per te prima di affidarti allo strumento.
Quando si installa Longhorn SDK, viene creato un set di voci di menu Start che è possibile usare per creare una sessione del prompt dei comandi in cui è possibile compilare applicazioni Longhorn. Per compilare versioni di debug dell'applicazione in un sistema a 32 bit di Microsoft Windows® XP, spostarsi tra le voci di menu seguenti per creare la sessione del prompt dei comandi appropriata:
- Inizio
- Programmi
- Microsoft Longhorn SDK
- Aprire la finestra Ambiente di compilazione
- Ambiente di compilazione a 32 bit di Windows XP
- Impostare l'ambiente di compilazione a 32 bit di Windows XP (debug)
Motore di compilazione Microsoft .NET: MSBuild.exe
MSBuild è lo strumento principale usato per compilare un'applicazione Longhorn. È possibile eseguire MSBuild con l'opzione della riga di comando della Guida per ottenere informazioni dettagliate sull'utilizzo:
MSBuild /?
Quando si esegue MSBuild senza argomenti della riga di comando, come illustrato di seguito, cerca nella directory di lavoro corrente un nome di file che termina con "proj", ad esempio .proj, .csproj e così via. Quando ne trova uno, compila il progetto in base alle direttive in tale file.
MSBuild
Quando nella directory sono presenti più file di progetto, è possibile specificare il file di progetto appropriato nella riga di comando:
MSBuild <ProjectName>.proj
In genere, MSBuild compila la destinazione predefinita nel file di progetto. È possibile eseguire l'override di questo e specificare la destinazione che si vuole compilare. Ad esempio, per compilare la destinazione denominata CleanBuild, richiamare MSBuild come indicato di seguito:
MSBuild /t:Cleanbuild
Compilazione di Hello World con MSBuild
Verranno ora esaminati i file necessari per creare una semplice applicazione Hello World basata sulla navigazione. Più avanti descriverò lo scopo e l'uso di ogni file in dettaglio.
Prima di tutto, è necessario definire l'oggetto application
HelloWorldApplication.xaml
<NavigationApplication xmlns="https://schemas.microsoft.com/2003/xaml"
StartupUri="HelloWorld.xaml" />
Questa definizione indica: "Per l'oggetto application di
Ecco il contenuto del file HelloWorld.xaml. È una versione leggermente più interessante dell'esempio Hello World precedente nel capitolo 1.
HelloWorld.xaml
<Border xmlns="https://schemas.microsoft.com/2003/xaml">
<FlowPanel>
<SimpleText Foreground="DarkRed" FontSize="14">Hello World!</SimpleText> </FlowPanel>
</Border>
Ora che ho tutto il "codice" per la mia semplice applicazione Hello World, ho bisogno di un file di progetto che definisce come compilare l'applicazione. Ecco il mio file HelloWorld.proj.
HelloWorld.proj
<Project DefaultTargets="Build">
<PropertyGroup>
<Property Language="C#" />
<Property DefaultClrNameSpace="IntroLonghorn" />
<Property TargetName="HelloWorld" />
</PropertyGroup>
<!--Imports the target which contains all the common targets-->
<Import Project="$(LAPI)\WindowsApplication.target" />
<ItemGroup>
<!-- Application markup -->
<Item Type="ApplicationDefinition" Include="HelloWorldApplication.xaml" />
<!-- Compiled Xaml Files list -->
<Item Type="Pages" Include="HelloWorld.xaml"/>
</ItemGroup>
</Project>
Inserire questi tre file in una directory. Aprire un prompt dei comandi di Longhorn SDK, passare alla directory contenente i file ed eseguire MSBuild. Compilerà il programma in un eseguibile.
Il contenuto del file di definizione dell'applicazione verrà esaminato più avanti in questo capitolo. Nel capitolo 3, descrivo in dettaglio molti degli elementi XAML (Extensible Application Markup Language) che puoi usare per definire un'interfaccia utente. Prima di esaminare il file di progetto in modo più approfondito, si esaminerà la terminologia di MSBuild.
Terminologia di MSBuild
Verranno ora stabilite definizioni per alcuni elementi di MSBuild. Un Property
<Property OutputDir="bin\" />
Si può pensare a un Item come una matrice di file. Un elemento può contenere caratteri jolly e può escludere file specifici. MSBuild usa l'attributo type
<Item Type="Compile" Include="*.cs" Exclude="DebugStuff.cs" />
Un Task è un'unità atomica nel processo di compilazione. Un Task di
- Attività degli strumenti .NET
- Attività di distribuzione
- Attività della shell
Ad esempio,
<Task Name="Csc" AssemblyName="$(OutputDir)\HelloWorld.exe"
Sources="@(Compile)" />
Un target è un singolo passaggio logico nel processo di compilazione. Un target
<Target Name="CopyToServer"
Inputs="$(OutputDir)\HelloWorld.exe"
Outputs="\\DeployServer\$(BuildNum)\HelloWorld.exe"
DependsOnTargets="Compile">
<Task Name="Copy" ... />
</Target>
Un attributo Condition
<PropertyGroup Condition=" '$(Configuration)'=='Debug' " >
<Property ... />
<Property ... />
</PropertyGroup>
Un Import equivale approssimativamente a un'istruzione #include C/C++, come illustrato nell'esempio seguente. Quando si importa un progetto, il contenuto del progetto importato diventa logicamente parte del progetto di importazione.
<Import Project="$(LAPI)\WindowsApplication.target" />
Ora che la terminologia non è corretta, esaminiamo un file di progetto tipico.
Compilazione di un'applicazione eseguibile Longhorn
Ecco un file di progetto semplice, ma relativamente completo, che compila un'applicazione Longhorn eseguibile:
<Project DefaultTargets="Build">
<PropertyGroup>
<Property Language="C#" />
<Property DefaultClrNameSpace="IntroLonghorn" />
<Property TargetName="MyApp" />
</PropertyGroup>
<Import Project="$(LAPI)\WindowsApplication.target" />
<ItemGroup>
<Item Type="ApplicationDefinition" Include="MyApp.xaml" />
<Item Type="Pages" Include="HomePage.xaml" />
<Item Type="Pages" Include="DetailPage.xaml" />
<Item Type="Code" Include="DetailPage.xaml.cs"/>
<Item Type="DependentProjects" Include="MyDependentAssembly.proj" />
<Item Type="Components" Include="SomeThirdParty.dll" />
<Item Type="Resources" Include="Picture1.jpg"
FileStorage="embedded" Localizable="False"/>
<Item Type="Resources" Include="Picture2.jpg"
FileStorage="embedded" Localizable="True"/>
</ItemGroup>
</Project>
Elemento Project
Tutti i file di progetto iniziano con una definizione di elemento radice denominata Project. L'attributo DefaultTargets specifica i nomi delle destinazioni che il sistema deve compilare quando non si specifica diversamente una destinazione. In questo esempio si specifica che, per impostazione predefinita, il sistema deve compilare la destinazione denominata Build.
Elementi propertygroup e
Le regole di compilazione possono essere eseguite in modo condizionale in base ai valori delle proprietà. Come accennato, il valore di una proprietà può provenire da una variabile di ambiente, da un'opzione della riga di comando di MSBuild o da una definizione di proprietà in un file di progetto.
Un progetto per un'applicazione deve specificare almeno un valore per le proprietà
Il sistema di compilazione compila ogni file XAML in una definizione di classe gestita. Per impostazione predefinita, la classe gestita avrà lo stesso nome del nome file di base del file di origine XAML. Ad esempio, il file Markup.xaml viene compilato in una definizione di una classe denominata Markup. Impostando la proprietà defaultClrNameSpace
Sono stati definiti le proprietà prima di importare altri progetti, quindi le regole nei progetti importati useranno i valori delle proprietà specificate, ad esempio si otterranno le regole di compilazione appropriate per le applicazioni C# perché si definisce la proprietà linguaggio di
Elemento Import
Le regole nella destinazione compilazione
<Import Project="$(LAPI)\WindowsApplication.target" />
Questo file importato contiene le regole di compilazione standard per la compilazione di un'applicazione Windows e definisce (indirettamente) la destinazione denominata Build.
Elementi itemgroup e item
L'elemento ItemGroup e gli elementi figlio Item definiscono tutte le parti necessarie per compilare l'applicazione.
È necessario disporre di un elemento
<Item Type="ApplicationDefinition" Include="MyApp.xaml" />
Ogni
<Item Type="Pages" Include="HomePage.xaml" />
<Item Type="Pages" Include="DetailPage.xaml" />
Ogni elemento
<Item Type="Code" Include="DetailPage.xaml.cs"/>
Questo progetto potrebbe dipendere da altri progetti. Il sistema di compilazione deve compilare questi progetti dipendenti prima di poter compilare questo progetto. Ogni progetto dipendente viene elencato usando un elemento
<Item Type="DependentProjects" Include="MyDependentAssembly.proj" />
Il codice in questo progetto può usare tipi in un assembly predefinito, noto anche come assembly del componente . Per compilare il codice usando tali assembly di componenti, il compilatore deve avere un riferimento a ogni assembly. Inoltre, quando si distribuisce l'applicazione, sarà necessario distribuire anche questi assembly di componenti. Ogni assembly di componenti viene elencato usando un elemento
<Item Type="Components" Include="SomeThirdParty.dll" />
Un assembly a cui si fa riferimento è leggermente diverso da un assembly del componente. In entrambi i casi, il codice usa tipi in un assembly predefinito. Tuttavia, non viene fornito un assembly a cui si fa riferimento come parte dell'applicazione, mentre si esegue la spedizione di un assembly di componenti come parte dell'applicazione. Il sistema di compilazione deve conoscere questa distinzione.
È necessario specificare un item
<Item Type="References" Include="SharedThirdParty.dll" />
L'applicazione potrebbe anche usare risorse. Un elemento
<Item Type="Resources" Include="Picture1.jpg"
FileStorage="embedded" Localizable="False"/>
<Item Type="Resources" Include="Picture2.jpg"
FileStorage="embedded" Localizable="True"/>
Creazione di un assembly della libreria Longhorn
È anche possibile creare librerie oltre alle applicazioni eseguibili. Le differenze principali tra un progetto di applicazione e un progetto di libreria sono le seguenti:
- Un progetto di libreria imposta il valore della proprietà TargetType
su Library . - Un progetto di libreria in genere non include un elemento di definizione dell'applicazione.
Ecco un esempio di file di progetto che crea una libreria:
<Project DefaultTargets="Build">
<PropertyGroup>
<Property Language="C#" />
<Property DefaultClrNameSpace="IntroLonghorn" />
<Property TargetName="MyLibrary" />
<Property TargetType="Library" />
</PropertyGroup>
<Import Project="$(LAPI)\WindowsApplication.target" />
<ItemGroup>
<Item Type="Pages" Include="ErrorPage.xaml" />
<Item Type="Code" Include="ErrorPage.xaml.cs"/>
<Item Type="Code" Include="Utilities.cs"/>
<Item Type="DependentProjects" Include="MyDependentAssembly.proj" />
<Item Type="Components" Include="SomeThirdParty.dll" />
<Item Type="Resources" Include="Picture1.jpg"
FileStorage="embedded" Localizable="False"/>
<Item Type="Resources" Include="Picture2.jpg"
FileStorage="embedded" Localizable="True"/>
</ItemGroup>
</Project>
Compilazione di un documento longhorn
Non è possibile creare applicazioni con XAML. Puoi anche usare i file XAML per creare un documento altamente interattivo, intelligentemente sottoposto a rendering, adattivo per consentire a un utente di leggere. In questo caso, i file XAML rappresentano collettivamente le pagine di un documento. È possibile usare il motore MSBuild per compilare tali documenti.
Le modifiche apportate al file di progetto per compilare un documento anziché un'applicazione sono minori:
- Impostare il valore della proprietà TargetType
su Document . - Importare il progetto WindowsDocument.target per le regole di compilazione appropriate.
- Includere tutti gli altri file di progetto come di consueto.
È importante comprendere cosa produce realmente un TargetType
Inoltre, quando si chiede a MSBuild di creare un file contenitore, compila ogni file XAML in una rappresentazione binaria del codice XML, denominato CODICE XAML binario (BAML). BAML è molto più compatto del file di testo originale o di un assemblyto-IL compilato. I file BAML vengono scaricati più rapidamente, ottimizzati per il download, ma un interprete deve analizzarli in fase di esecuzione per creare istanze delle classi descritte nel file. Pertanto, tali file non sono ottimizzati per la velocità. Fino ad ora, ho generato file compilatito-IL (noti anche come file CAML, in breve per XAML compilato).
Ecco un esempio di file di progetto che crea un documento elettronico:
<Project DefaultTargets="Build">
<PropertyGroup>
<Property TargetType="Document" />
<Property Language="C#" />
<Property DefaultClrNameSpace="IntroLonghorn" />
<Property TargetName="MyDocument" />
</PropertyGroup>
<Import Project="$(LAPI)\WindowsDocument.target" />
<ItemGroup>
<Item Type="ApplicationDefinition" Include="MyApp.xaml" />
<Item Type="Pages" Include="Markup.xaml" />
<Item Type="Pages" Include="Navigate.xaml" />
<Item Type="Code" Include="Navigate.xaml.cs"/>
<Item Type="Resources" Include="Picture1.jpg"
FileStorage="embedded" Localizable="False"/>
<Item Type="Resources" Include="Picture2.jpg"
FileStorage="embedded" Localizable="True"/>
</ItemGroup>
</Project>
Ora che hai appreso come creare i vari tipi di applicazioni e componenti longhorn, esaminiamo in modo più dettagliato i file XAML. In particolare, esaminiamo cosa fa il sistema di compilazione quando trasforma un file XAML in una classe .NET.
Un file XAML come dichiarazione di classe
Il file di definizione dell'applicazione è il file XAML che definisce la classe dell'oggetto 'applicazione dell'applicazione. Tuttavia, in generale, un documento XAML è semplicemente un file che definisce una classe. La classe prodotta dalla definizione XAML deriva dalla classe associata al nome dell'elemento radice del documento XML. Per impostazione predefinita, il sistema di compilazione usa il nome del file di base XAML come nome della classe generata.
Creazione di un file di definizione dell'applicazione per un'applicazione di spostamento
Tenere presente che l'elemento item
Nel capitolo 1 è stato illustrato come creare e usare un'istanza dell'applicazione a livello di codice. Il file XAML seguente usa il markup per definire l'oggetto application
<NavigationApplication xmlns="https://schemas.microsoft.com/2003/xaml"
StartupUri="HelloWorld.xaml" />
Si prevede che la maggior parte delle applicazioni Longhorn sarà basata sulla navigazione e, pertanto, spesso riutilicherà semplicemente l'oggetto NavigationApplication standard. È possibile riutilizzare questo file di definizione dell'applicazione per la maggior parte delle applicazioni basate sulla navigazione modificando solo il valore dell'attributo StartupUri
Ad esempio, se la definizione dell'applicazione precedente si trova nel file HelloWorldApplication.xaml e uso il file di progetto HelloWorld.proj elencato in precedenza, il sistema di compilazione produce la dichiarazione di classe seguente:
namespace IntroLonghorn {
class HelloWorldApplication :
MSAvalon.Windows.Navigation.NavigationApplication {
.
.
.
}
}
Lo spazio dei nomi risultante dalla dichiarazione DefaultClrNameSpace
Personalizzazione del codice generato tramite attributi
Quando dichiari un elemento radice in un file XAML, puoi usare attributi sull'elemento radice per controllare il nome della dichiarazione di classe generata. È possibile usare uno degli attributi facoltativi seguenti:
- Definizione del prefisso dello spazio dei nomi che associa un prefisso a uno spazio dei nomi denominato Definizione. È necessario definire un prefisso per questo spazio dei nomi per usare gli attributi Language
e Class . Tradizionalmente, viene usato il prefissodef. - Attributo
language (definito nello spazio dei nomi definizione ) che specifica il linguaggio di programmazione usato da qualsiasi codice inline nel file XAML. - Attributo classe
(definito nello spazio dei nomi definizione ) che specifica il nome della classe generata. Quando si specifica un nome contenente uno o più punti, il sistema di compilazione non antepone il nome al valore DefaultClrNameSpace.
Ad esempio, si modificherà il contenuto del file HelloWorldApplication.xaml nel modo seguente:
<NavigationApplication xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
def:Class="Special.MyApp"
def:CodeBehind="HelloWorldApplication.xaml.cs"
StartupUri="HelloWorld.xaml" />
La classe generata sarà quindi la seguente:
namespace Special {
class MyApp :
MSAvalon.Windows.Navigation.NavigationApplication {
.
.
.
}
}
Uso di codice e markup nella stessa classe
Quasi tutte le applicazioni richiederanno di scrivere codice, ad esempio un gestore eventi click per un pulsante o un override del metodo virtuale, oltre al markup che specifica l'interfaccia utente. Ricordare dal capitolo 1 che l'applicazione non basata su navigazione esegue l'overrode del metodo OnStartingUp per creare la finestra e i controlli. Questo esempio verrà riscritto per illustrare come combinare il codice dell'applicazione e il markup.
Anche se questo prossimo esempio crea un'applicazione non di navigazione, voglio sottolineare che non c'è davvero motivo interessante per creare un'applicazione di questo tipo. È sempre possibile creare un'applicazione basata sulla navigazione che non passa mai effettivamente a una pagina diversa. Tuttavia, la scrittura di un'applicazione di questo tipo richiede di combinare codice e markup nella stessa classe, pertanto fornisce un buon esempio.
Tenere presente che la creazione di un'applicazione non di spostamento richiede di definire una classe personalizzata che eredita da MSAvalon.Windows.Application e che esegue l'override del metodo OnStartingUp. Il file di definizione dell'applicazione dichiara la classe oggetto applicazione usata dal programma. Pertanto, un'applicazione non di navigazione deve definirne l'override metodo OnStartingUp nella stessa classe.
Ad eccezione delle modifiche seguenti, un file di configurazione dell'applicazione per un'applicazione non di navigazione contiene gli stessi elementi di un file di definizione per un'applicazione di navigazione:
- L'elemento radice è Application anziché NavigationApplication.
- Il file deve contenere o fare riferimento all'implementazione del metodo OnStartingUp per la classe dell'applicazione.
Poiché devo usare markup e codice per implementare una singola classe, devo mostrare una tecnica per associare un file di codice sorgente a un file XAML.
Associazione di un file Source-Behind a un file XAML
Spesso si vogliono sviluppare parti dell'applicazione usando markup e per sviluppare altre parti usando un linguaggio di programmazione più tradizionale. È consigliabile separare l'interfaccia utente e la logica in singoli file di origine usando la tecnica seguente.
Puoi aggiungere un elemento
Ecco una definizione XAML che produce una classe di applicazione non di navigazione equivalente al primo esempio del capitolo 1:
<Application xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
def:Language="C#"
def:Class="IntroLonghorn.CodeBehindSample"
def:CodeBehind="CodeBehind.xaml.cs" />
Esistono due aspetti importanti per questo file di definizione dell'applicazione:
- L'attributo linguaggio
specifica che il file code-behind contiene codice sorgente C#. - L'attributo codeBehind
specifica che il nome del file di origine è CodeBehindMySample2.xaml.cs.
Ecco il file source-behind corrispondente:
namespace IntroLonghorn {
using System;
using MSAvalon.Windows;
using MSAvalon.Windows.Controls;
using MSAvalon.Windows.Media;
public partial class CodeBehindSample {
MSAvalon.Windows.Controls.SimpleText txtElement;
MSAvalon.Windows.Window mainWindow;
protected override
void OnStartingUp (StartingUpCancelEventArgs e) {
base.OnStartingUp (e);
CreateAndShowMainWindow ();
}
private void CreateAndShowMainWindow () {
// Create the application's main window
mainWindow = new MSAvalon.Windows.Window ();
// Add a dark red, 14 point, "Hello World!" text element
txtElement = new MSAvalon.Windows.Controls.SimpleText ();
txtElement.Text = "Hello World!";
txtElement.Foreground = new
MSAvalon.Windows.Media.SolidColorBrush (Colors.DarkRed);
txtElement.FontSize = new FontSize (14,
FontSizeType.Point);
mainWindow.Children.Add (txtElement);
mainWindow.Show ();
}
}
}
Si noti la parola chiave parziale nella dichiarazione di classe nel file code-behind. Questa parola chiave indica che il compilatore deve unire questa definizione di classe con altre definizioni della stessa classe. In questo modo è possibile fornire più definizioni parziali di una classe, ognuna in un file di origine separato, che il compilatore combina in una singola definizione di classe nell'assembly risultante.
Combinazione di codice sorgente e markup in un singolo file XAML
Penso che sia sbagliato combinare codice sorgente e markup nello stesso file. Ho anche pensato di non mostrarti come farlo. Tuttavia, un po ' maledoer scriverà un programma di esempio usando questa tecnica, quindi potrebbe essere necessario capire cosa ha fatto. Inoltre, è possibile usare l'approccio code-behind descritto in precedenza per eliminare il mondo di una piccola quantità di male e separare l'interfaccia utente dalla logica.
Ecco un file di definizione dell'applicazione con il codice sorgente inserito direttamente inline con il markup :
<Application xmlns="https://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
def:Language="C#"
def:Class="IntroLonghorn.MySample2" >
<def:Code>
<![CDATA[
protected override void OnStartingUp (StartingUpCancelEventArgs e) {
base.OnStartingUp (e);
CreateAndShowMainWindow ();
}
. . . Remaining methods elided for clarity
]]>
</def:Code>
</Application>
In questo esempio, l'attributo language
Mi scuso ancora una volta per mostrarti una tale travestitura.
Manifesto dell'applicazione
Quando si compila un'applicazione, MSBuild produce il file .exe più due file manifesto: il manifesto dell'applicazione, *.manifest e un manifesto di distribuzione, *.deploy. Questi manifesti vengono usati quando si distribuisce un'applicazione o un documento da un server. Copiare prima di tutto l'applicazione, tutte le relative dipendenze e i due file manifesto nel percorso appropriato nel server. In secondo luogo, modificare il manifesto della distribuzione in modo che punti al percorso del manifesto dell'applicazione.
Per completezza, esaminiamo gli esempi dei manifesti dell'applicazione e della distribuzione. Il manifesto dell'applicazione, illustrato nell'esempio seguente, non è effettivamente interessante come il manifesto della distribuzione. Il manifesto dell'applicazione definisce semplicemente tutte le parti che costituiscono un'applicazione. MSBuild genera il manifesto dell'applicazione quando compila l'applicazione e in genere si modifica poco o nulla in esso.
HelloWorld.manifest
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"
xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd">
<assemblyIdentity name="HelloWorld" version="1.0.0.0"
processorArchitecture="x86" asmv2:culture="en-us"
publicKeyToken="0000000000000000" />
<entryPoint name="main" xmlns="urn:schemas-microsoft-com:asm.v2"
dependencyName="HelloWorld">
<commandLine file="HelloWorld.exe" parameters="" />
</entryPoint>
<TrustInfo xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:temp="temporary">
<Security>
<ApplicationRequestMinimum>
<PermissionSet class="System.Security.PermissionSet" version="1"
ID="SeeDefinition">
<IPermission
class="System.Security.Permissions.FileDialogPermission"
version="1" Unrestricted="true" />
<IPermission
class="System.Security.Permissions.IsolatedStorageFilePermission"
version="1" Allowed="DomainIsolationByUser" UserQuota="5242880" />
<IPermission
class="System.Security.Permissions.SecurityPermission"
version="1" Flags="Execution" />
<IPermission
class="System.Security.Permissions.UIPermission" version="1"
Window="SafeTopLevelWindows" Clipboard="OwnClipboard" />
<IPermission
class="System.Security.Permissions.PrintingPermission"
version="1" Level="SafePrinting" />
<IPermission
class="MSAvalon.Windows.AVTempUIPermission, PresentationFramework,
Version=6.0.4030.0, Culture=neutral,
PublicKeyToken=a29c01bbd4e39ac5" version="1"
NewWindow="LaunchNewWindows" FullScreen="SafeFullScreen" />
</PermissionSet>
<AssemblyRequest name="HelloWorld"
PermissionSetReference="SeeDefinition" />
</ApplicationRequestMinimum>
</Security>
</TrustInfo>
<dependency asmv2:name="HelloWorld">
<dependentAssembly>
<assemblyIdentity name="HelloWorld" version="0.0.0.0"
processorArchitecture="x86" />
</dependentAssembly>
<asmv2:installFrom codebase="HelloWorld.exe"
hash="5c58153494c16296d9cab877136c3f106785bfab"
hashalg="SHA1" size="5632" />
</dependency>
</assembly>
La maggior parte del contenuto del manifesto dell'applicazione dovrebbe essere relativamente ovvia. L'elemento entryPoint
L'elemento
Longhorn Trust Manager usa l'elemento
Manifesto della distribuzione
Come accennato, il manifesto della distribuzione è più interessante. Il manifesto della distribuzione contiene, ovviamente, impostazioni sufficienti che controllano la distribuzione dell'applicazione.
HelloWorld.deploy
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"
xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd">
<assemblyIdentity name="HelloWorld.deploy" version="1.0.0.0"
processorArchitecture="x86" asmv2:culture="en-us"
publicKeyToken="0000000000000000" />
<description asmv2:publisher="Wise Owl, Inc."
asmv2:product="Brent's HelloWorld Application"
asmv2:supportUrl="http://www.wiseowl.com/AppServer/HelloWorld/support.asp"
/>
<deployment xmlns="urn:schemas-microsoft-com:asm.v2"
isRequiredUpdate="false">
<install shellVisible="true" />
<subscription>
<update>
<beforeApplicationStartup />
<periodic>
<minElapsedTimeAllowed time="6" unit="hours" />
<maxElapsedTimeAllowed time="1" unit="weeks" />
</periodic>
</update>
</subscription>
</deployment>
<dependency>
<dependentAssembly>
<assemblyIdentity name="HelloWorld" version="1.0.0.0"
processorArchitecture="x86" asmv2:culture="en-us"
publicKeyToken="0000000000000000" />
</dependentAssembly>
<asmv2:installFrom codebase="HelloWorld.manifest" />
</dependency>
</assembly>
Il manifesto della distribuzione contiene informazioni richieste da Longhorn per installare e aggiornare un'applicazione. Si noti che l'elemento assemblyIdentity del manifesto della distribuzione fa riferimento al manifesto dell'applicazione. Dopo tutto, il manifesto dell'applicazione descrive già tutti i componenti di un'applicazione. Per installare un'applicazione, il manifesto della distribuzione indica, in effetti, "Ecco la descrizione dei file necessari per installare l'applicazione".
Naturalmente, quando si installa un'applicazione, sono necessarie anche altre informazioni rispetto ai file da copiare in un sistema. L'elemento description
L'elemento distribuzione
Esecuzione dell'applicazione
In genere, un utente "eseguirà" il manifesto dell'applicazione per eseguire l'applicazione dal server direttamente senza installare l'applicazione nel computer locale. Longhorn scarica i componenti dell'applicazione in base alle esigenze. In questo caso, il server deve essere disponibile per eseguire l'applicazione.
Quando un utente "esegue" il manifesto della distribuzione, Longhorn scarica e installa l'applicazione nel computer locale. L'applicazione può installare icone sul desktop, aggiungere voci di menu Start e in genere diventare un'applicazione installata tradizionale. Naturalmente, si ottengono anche gli aggiornamenti in background automatici, il rollback della versione e il supporto per la disinstallazione.
Quando si avvia per la prima volta un manifesto di distribuzione, Longhorn installa l'applicazione nella cache dell'applicazione e aggiunge una voce all'elenco Installazione applicazioni del Pannello di controllo. Successivamente, ogni volta che si esegue il manifesto della distribuzione, l'applicazione viene caricata direttamente dalla cache dell'applicazione. In genere non viene scaricato di nuovo.
Tuttavia, quando si disinstalla l'applicazione dalla cache usando l'applet Installazione applicazioni del Pannello di controllo, successivamente l'esecuzione del manifesto di distribuzione scarica e installa nuovamente l'applicazione.
In alternativa, è possibile modificare il numero di versione dell'applicazione nel server. Quindi, quando si esegue il manifesto della distribuzione, Longhorn scaricherà e installerà la nuova versione side-by-side con la versione corrente. Entrambe le versioni dell'applicazione verranno visualizzate nell'elenco Installazione applicazioni.
Perché creare un altro sistema di compilazione?
Mi piace molto MSBuild, anche se, al momento della stesura di questo articolo, ho avuto solo poche settimane di esperienza con esso. Naturalmente, anni di esperienza con makefiles rende il sistema di compilazione più elegante attraente. Attualmente, esistono due sistemi di compilazione alternativi in uso comune: Make e Ant. Sembra naturale confrontare MSBuild con tali alternative.
Perché non usare make?
Perché sviluppare un nuovo sistema di compilazione quando molti sviluppatori hanno familiarità con uno esistente denominato Make? Make ha una scarsa integrazione degli strumenti nel sistema di compilazione. Eseguire semplicemente i comandi della shell. Per questo motivo, non esiste alcuna capacità intrinseca per uno strumento di comunicare con un altro strumento durante il processo di compilazione. MSBuild crea istanze delle classi di Task e le attività possono comunicare tra loro passando tipi .NET normali.
I makefile hanno una sintassi insolita, sono difficili da scrivere e non sono scalabili correttamente, perché diventano complessi per progetti di grandi dimensioni. Inoltre, gli strumenti diversi da Make non possono elaborare facilmente un makefile. Gli strumenti diversi da MSBuild possono generare e analizzare facilmente la sintassi basata su XML di un progetto MSBuild.
Infine, Make non ha davvero supporto per i progetti. Non esiste alcuna astrazione del file system e nessun supporto per le proprietà a catena. Inoltre, non esiste alcun supporto in fase di progettazione per la generazione di un makefile.
Perché non usare Ant?
Una domanda frequente simile è il motivo per cui sviluppare un nuovo sistema di compilazione basato su XML quando esiste un sistema di successo e ricco esistente chiamato Ant? Ant è un sistema di compilazione open source Java di Apache.org che ha introdotto i file e le attività di progetto basati su XML come operazione di compilazione atomica. È disponibile anche una grande porta .NET di Ant denominata NAnt disponibile da nant.sourceforge.net. Sulla superficie, MSBuild e Ant/NAnt sono simili. Entrambi gli strumenti usano XML come formato di serializzazione del progetto e entrambi gli strumenti usano attività come unità atomica dell'operazione di compilazione. Entrambi gli strumenti hanno i loro punti di forza, ma quando si esaminano più da vicino hanno obiettivi di progettazione diversi.
Ant ha deciso di impostare molte funzionalità in un ampio set di attività. MSBuild ha un obiettivo di progettazione diverso, in cui la funzionalità simile viene incapsulata dal motore ,ad esempio l'analisi del timestamp, la comunicazione intertask tramite elementi, invio in batch di attività, trasformazioni di elementi e così via. Entrambi gli approcci hanno i loro punti di forza e debolezza.
Il modello di Ant consente agli sviluppatori di estendere e controllare ogni dettaglio della compilazione e quindi è molto flessibile. Tuttavia, pone anche una maggiore responsabilità sui writer di attività perché le attività devono essere molto più sofisticate per fornire funzionalità coerenti. Il modello di MSBuild riduce la quantità di funzionalità che ogni attività deve implementare. Gli autori di progetti possono quindi basarsi su funzionalità coerenti in progetti, destinazioni e attività diversi. Inoltre, gli ambienti di sviluppo integrati come Visual Studio possono anche basarsi su tali servizi per offrire risultati coerenti e un'esperienza utente avanzata, senza dover conoscere gli elementi interni delle attività chiamate durante il processo di compilazione.
Analogamente, mentre Ant ha il concetto di script di compilazione, non ha il concetto di manifesto del progetto che MSBuild ha. Uno script di compilazione indica come creare un set di file, ma non fornisce semantiche aggiuntive che descrivono come vengono usati i file. Un manifesto descrive inoltre la semantica dei file, che consente strumenti aggiuntivi, ad esempio un IDE, di integrarsi più profondamente con il sistema di compilazione. Al contrario, la mancanza di un manifesto del progetto significa che uno sviluppatore può più facilmente personalizzare Ant per creare nuovi tipi di "roba" perché non esiste uno schema con vincolo per lo script di compilazione.
Sommario
Ora hai appreso le nozioni di base. È possibile scrivere XAML e compilare, distribuire ed eseguire l'applicazione risultante. Sfortunatamente, le applicazioni che hai imparato a scrivere finora sono abbastanza noiose. capitolo 3 immergersi in modo approfondito in XAML e illustra come usare un'ampia gamma di oggetti dell'interfaccia utente forniti dalla piattaforma Longhorn. I capitoli successivi mostrano una serie di altre nuove tecnologie che è possibile usare anche nelle applicazioni.