Condividi tramite


Compilazione di un'applicazione WPF

Aggiornamento: Luglio 2008

Le applicazioni Windows Presentation Foundation (WPF) possono essere compilate come file eseguibili .NET Framework (.exe), librerie (.dll) o come combinazione dei due tipi di assembly. In questo argomento viene inizialmente illustrato come compilare applicazioni WPF semplici dal prompt dei comandi. Successivamente viene illustrato il modo in cui WPF sfrutta l'estensibilità di Microsoft Build Engine (MSBuild) per compilare applicazioni più complesse. Infine vengono fornite informazioni dettagliate sui principali passaggi che costituiscono il processo di compilazione MSBuild.

Nel presente argomento sono contenute le seguenti sezioni.

  • Compilazione di un'applicazione WPF mediante la riga di comando
  • Compilazione di un'applicazione WPF mediante MSBuild
  • File di progetto MSBuild per WPF
  • Creazione di un progetto MSBuild per WPF mediante Visual Studio
  • Compilazione di un progetto MSBuild per WPF
  • Pipeline di compilazione Windows Presentation Foundation
  • Supporto per compilazioni incrementali
  • Argomenti correlati

Compilazione di un'applicazione WPF mediante la riga di comando

Un'applicazione WPF interamente scritta in codice, senza l'utilizzo del markup, può essere compilata mediante un compilatore da riga di comando. Si consideri ad esempio un'applicazione autonoma WPF in C# che include i seguenti file di codice sorgente:

  • Un file di definizione dell'applicazione (app.cs).

  • Una finestra (mainwindow.cs).

Questa applicazione può essere compilata utilizzando il compilatore C#, csc.exe, da un prompt dei comandi, come illustrato nel seguente esempio:

csc.exe
  /out:WPFApplication.exe
  /target:winexe 
  app.cs mainwindow.cs 
  /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\presentationframework.dll" 
  /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\windowsbase.dll" 
  /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\presentationcore.dll"

In questo esempio:

  • Il parametro /out specifica il nome dell'assembly eseguibile compilato (WPFApplication.exe).

  • Il parametro /target specifica il tipo di assembly compilato (un eseguibile Microsoft Windows).

  • Vengono specificati i file di codice sorgente C# che costituiscono l'applicazione (app.cs e mainwindow.cs).

  • Il parametro /reference identifica gli assembly a cui si fa riferimento che implementano i tipi utilizzati dall'applicazione.

La compilazione dalla riga di comando può essere utilizzata per compilare applicazioni più complesse, benché il compilatore non supporti le applicazioni WPF che includono codice sorgente Extensible Application Markup Language (XAML). Inoltre la compilazione dalla riga di comando non supporta l'intera gamma dei requisiti di compilazione delle applicazioni WPF tipiche, inclusa la gestione della configurazione e la generazione di manifesti ClickOnce. Per supportare questi e altri requisiti di compilazione più complessi, WPF integra ed estende MSBuild.

Nota

Per ulteriori informazioni sulla compilazione dalla riga di comando, vedere Compilazione dalla riga di comando con csc.exe oppure Compilazione dalla riga di comando (Visual Basic).

Compilazione di un'applicazione WPF mediante MSBuild

MSBuild è una tecnologia affidabile ed estensibile introdotta con .NET Framework. La base della tecnologia MSBuild viene implementata attraverso gli assembly descritti nella tabella seguente.

Assembly

Descrizione

Microsoft.Build.Engine.dll

Legge ed elabora i file di progetto MSBuild.

Microsoft.Build.Tasks.dll

Implementa funzionalità comuni a tutti i progetti MSBuild, inclusa la chiamata al compilatore da riga di comando (ad esempio, csc.exe per C# e vbc.exe per Visual Basic).

Microsoft.Build.Utilities.dll

Espone le classi di utilità che estendono MSBuild con funzionalità di compilazione personalizzate.

Microsoft.Build.Framework.dll

Implementa le interfacce che definiscono l'interazione tra le funzionalità MSBuild e il motore MSBuild.

Microsoft.Build.Conversion.dll

Supporta la conversione dal formato dei file di progetto Microsoft Visual Studio .NET 2002 e Microsoft Visual Studio .NET 2003 legacy al formato dei file di progetto MSBuild Microsoft Visual Studio 2005.

Nota

Per ulteriori informazioni sugli assembly MSBuild, vedere Riferimenti a MSBuild.

File di progetto MSBuild per WPF

Gli assembly che costituiscono MSBuild vengono definiti motore MSBuild. Per la compilazione di applicazioni, il motore MSBuild richiede in genere le seguenti informazioni:

  • Riferimenti ai file di codice sorgente.

  • Riferimenti agli assembly dipendenti.

  • Dettagli di configurazione.

  • Requisiti di compilazione.

Per poter essere elaborate da MSBuild, queste informazioni vengono assemblate in file XML conformi allo schema MSBuild personalizzato (vedere Riferimenti dello schema del file di progetto MSBuild). Tali file vengono definiti file di progetto MSBuild. Di seguito viene riportato il file di progetto MSBuild per una versione dell'applicazione WPF compilata in precedenza utilizzando un compilatore da riga di comando, con l'aggiunta di file di codice sorgente Extensible Application Markup Language (XAML).

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     <PropertyGroup>
         <AssemblyName>WPFApplication</AssemblyName>
         <OutputType>winexe</OutputType>
     </PropertyGroup>
     <ItemGroup>
         <Reference Include="System" />
         <Reference Include="WindowsBase" />
         <Reference Include="PresentationCore" />
         <Reference Include="PresentationFramework" />
     </ItemGroup>
     <ItemGroup>
         <ApplicationDefinition Include="App.xaml" />
         <Compile Include="App.xaml.cs" />
         <Page Include="MainWindow.xaml" />
         <Compile Include="MainWindow.xaml.cs" />
     </ItemGroup>
     <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
     <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
</Project>

In questo esempio sono contenuti gli elementi comuni alla maggior parte dei file di progetto MSBuild, tra cui il tag Project, proprietà, elementi, destinazioni e attività.

Elemento Project

Come specificato dal relativo schema, un file di progetto MSBuild è un file XML nel quale Project è l'elemento di primo livello:

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     ...
</Project>

L'elemento Project rappresenta il punto dal quale il motore MSBuild inizia a elaborare il file di progetto. Per specificare la versione di MSBuild di destinazione per il file di progetto MSBuild, viene fornita una dichiarazione dello spazio dei nomi XML appropriata.

Proprietà

Le proprietà sono variabili utilizzate per configurare i progetti MSBuild e fornire informazioni specifiche della compilazione al motore MSBuild. Le proprietà sono contenute all'interno di elementi PropertyGroup, come illustrato nell'esempio che segue.

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     <PropertyGroup>
         <AssemblyName>WPFApplication</AssemblyName>
         <OutputType>winexe</OutputType>
     </PropertyGroup>
     ...
</Project>

Alcune proprietà, ad esempio AssemblyName e OutputType, sono comuni a tutti i tipi di applicazione e sono descritte in Proprietà di progetto MSBuild comuni. Nella tabella che segue vengono elencate le proprietà MSBuild specifiche di WPF.

Property

Descrizione

OutputType

Specifica il tipo di assembly compilato e può assumere uno dei seguenti valori:

  • winexe: compila un assembly eseguibile (.exe). Le applicazioni autonome e le applicazioni XBAP sono configurate con questo tipo di output.

  • library: compila un assembly di librerie (.dll). Gli assembly condivisi e le librerie di controlli personalizzati sono configurati con questo tipo di output.

HostInBrowser

Specifica se un'applicazione WPF è ospitata in un browser e può assumere uno dei seguenti valori:

  • true: crea un'applicazione XBAP che include l'assembly principale dell'applicazione (.exe), un manifesto di distribuzione (nomeApplicazione.xbap) e un manifesto dell'applicazione (nomeApplicazione.exe.manifest).

  • false: crea un'applicazione autonoma.

Se HostInBrowser è impostato su true, OutputType deve essere winexe.

Install

Specifica se un'applicazione XBAP è installata nel client. Install può essere true o false e assume il valore opposto rispetto a HostInBrowser.

GenerateManifests

Specifica se un'applicazione autonoma viene pubblicata mediante distribuzione ClickOnce e può assumere uno dei seguenti valori:

  • true: crea l'eseguibile principale dell'applicazione, un manifesto di distribuzione (nomeApplicazione.application) e un manifesto dell'applicazione (nomeApplicazione.exe.manifest).

  • false: crea solo l'eseguibile dell'applicazione (.exe).

GenerateManifests viene utilizzato soltanto quando il valore di Install è true.

UICulture

Specifica le impostazioni locali per cui verrà compilato l'assembly. Se specificata, i file dichiarati come elementi di progetto Resource e le risorse specifiche della lingua vengono compilati in un assembly satellite per le impostazioni locali desiderate. Il contenuto indipendente dalla lingua viene invece compilato nell'assembly principale. Per impostazione predefinita le applicazioni non vengono localizzate e, di conseguenza, i file di risorse vengono incorporati nell'assembly principale.

Nota

Quando si imposta UICulture, occorre specificare la lingua risorse neutra utilizzando NeutralResourcesLanguageAttribute. Questo attributo deve essere aggiunto al file AssemblyInfo di un'applicazione WPF.

Elementi

Gli elementi sono input MSBuild elaborati dal motore MSBuild durante il processo di compilazione. Gli elementi sono contenuti all'interno di un elemento ItemGroup.

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     ...
     <ItemGroup>
         <Reference Include="System" />
         <Reference Include="WindowsBase" />
         <Reference Include="PresentationCore" />
         <Reference Include="PresentationFramework" />
     </ItemGroup>
     <ItemGroup>
         <ApplicationDefinition Include="App.xaml" />
         <Compile Include="App.xaml.cs" />
         <Page Include="MainWindow.xaml" />
         <Compile Include="MainWindow.xaml.cs" />
     </ItemGroup>
     ...
</Project>

Il tipo di un elemento può essere configurato tramite metadati. Nell'esempio precedente, i riferimenti agli assembly sono configurati come elementi Reference, mentre i file di codice sorgente sono configurati come elementi Compile. Gli elementi Reference e Compile sono comuni a tutte le applicazioni .NET Framework e vengono descritti nel dettaglio in Elementi di progetto MSBuild comuni.

Nella tabella riportata di seguito sono elencati gli elementi MSBuild specifici di WPF.

Property

Descrizione

ApplicationDefinition

Identifica il file di markup XAML contenente la definizione di applicazione, ovvero un file di markup XAML il cui elemento radice è Application. ApplicationDefinition è obbligatoria quando Install è true e OutputType è winexe. Un'applicazione WPF e, di conseguenza, un progetto MSBuild possono avere un'unica proprietà ApplicationDefinition.

Page

Identifica un file di markup XAML il cui contenuto viene convertito in un formato binario e compilato in un assembly. Gli elementi Page vengono in genere implementati con una classe code-behind.

Gli elementi Page più comuni sono i file XAML il cui elemento di primo livello è uno dei seguenti:

Resource

Identifica un file di risorse compilato in un assembly dell'applicazione. Come detto in precedenza, UICulture elabora elementi Resource.

Content

Identifica un file di dati distribuito con un'applicazione. I metadati che descrivono il file di dati vengono compilati nell'applicazione mediante AssemblyAssociatedContentFileAttribute.

SplashScreen

Identifica un file di immagine utilizzato per la finestra di avvio dell'applicazione. L'assembly PresentationBuildTasks genera codice in App.g.cs o Application.g.vb che crea un'istanza di SplashScreen e lo visualizza mentre viene caricata l'applicazione. Questo elemento è disponibile a partire da Visual Studio 2008 SP1.

Destinazioni

Le destinazioni determinano il modo in cui i progetti vengono compilati e dipendono dalle proprietà e dagli elementi. Un'applicazione WPF deve avere una destinazione specifica del linguaggio e una destinazione specifica di WPF.

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     ...
     <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
     <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
</Project>

Le destinazioni sono file separati che terminano con l'estensione targets. I file di destinazione inclusi con .NET Framework sono installati nel percorso seguente:

%WINDIR%\Microsoft.NET\Framework\vX.X.X

La destinazione specifica del linguaggio compila codice sorgente specifico del linguaggio. La destinazione specifica del linguaggio per C# è Microsoft.CSharp.targets, mentre Microsoft.VisualBasic.targets è la destinazione per Visual Basic. Entrambe le destinazioni derivano da ed estendono la destinazione Microsoft.Common.targets, la quale esegue gran parte delle operazioni di compilazione comuni e indipendenti dal linguaggio. Per ulteriori informazioni sulle destinazioni MSBuild comuni e specifiche del linguaggio, vedere File con estensione targets di MSBuild.

Le operazioni di compilazione specifiche di WPF vengono eseguite dalla destinazione Microsoft.WinFX.targets e includono la compilazione del markup XAML, la generazione di manifesti per le applicazioni XBAP e l'elaborazione dei file di risorse e di dati WPF.

Attività

Un'attività è una classe che esegue un'azione di compilazione specifica. Le destinazioni combinano una o più attività per definire un processo di compilazione. Quando MSBuild elabora una destinazione, esegue le attività contenute al suo interno. Le attività utilizzate dalle destinazioni comuni e specifiche del linguaggio sono implementate dall'assembly Microsoft.Build.Tasks, mentre le attività specifiche di WPF sono implementate dall'assembly PresentationBuildTasks.

Le destinazioni forniscono il supporto di compilazione per tutte le applicazioni WPF standard. È anche possibile utilizzare combinazioni di attività alternative per implementare un comportamento di compilazione personalizzato. Ad esempio, l'attività GetWinFXPath MSBuild che segue viene utilizzata per rilevare il percorso nativo del runtime .NET Framework, il quale dipende dal fatto che l'attività venga o meno eseguita in un processore a 64 bit:

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
     <UsingTask 
         TaskName="Microsoft.Build.Tasks.Windows.GetWinFXPath" 
         AssemblyFile="C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationBuildTasks.dll" />
     <Target Name="GetWinFXPathTask">
         <GetWinFXPath
             WinFXNativePath="c:\DOTNet3Native" 
             WinFXWowPath="c:\DOTNet3WowNative" />
     </Target>
     <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
</Project>

Per ulteriori informazioni sulle attività MSBuild comuni, vedere Riferimenti delle attività MSBuild.

Esempi Windows Presentation Foundation MSBuild Project

Windows Software Development Kit (SDK) include diversi esempi di file di progetto MSBuild per i tipi più comuni di applicazioni WPF:

Creazione di un progetto MSBuild per WPF mediante Visual Studio

Visual Studio genera automaticamente i file di progetto MSBuild nel momento in cui vengono create nuove applicazioni WPF utilizzando modelli di progetto Visual Studio. Ad esempio, il modello di progetto di applicazione WPF genera il seguente file di progetto per C#:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.20726</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E0EA3EBA-718C-4122-B20C-EB97B7DC6604}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>WpfApplication1</RootNamespace>
    <AssemblyName>WpfApplication1</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>
      {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};
      {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
    </ProjectTypeGuids>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Xml.Linq">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data.DataSetExtensions">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
  </ItemGroup>
  <ItemGroup>
    <ApplicationDefinition Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>
    <Page Include="Window1.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="App.xaml.cs">
      <DependentUpon>App.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Window1.xaml.cs">
      <DependentUpon>Window1.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Properties\AssemblyInfo.cs">
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <AppDesigner Include="Properties\" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

Il nome dell'estensione del file di progetto MSBuild generato incorpora il linguaggio del codice sorgente:

  • Per i progetti C#, l'estensione è csproj.

  • Per i progetti Visual Basic, l'estensione è vbproj.

La dimensione del file di progetto è superiore rispetto agli esempi precedenti, in parte per la presenza di diverse proprietà aggiuntive. Tuttavia, le informazioni aggiuntive sono specifiche di Visual Studio e includono quanto segue:

  • La configurazione del progetto.

  • La configurazione di compilazione.

  • L'associazione dei file di codice sorgente.

  • La gestione di proprietà, risorse e impostazioni predefinite del progetto.

Configurazione del progetto

I dettagli di configurazione del progetto includono un identificatore univoco per il progetto, un identificatore univoco per il tipo di progetto e vari dati che identificano la versione di .NET Framework e Visual Studio:

<Project 
  ToolsVersion="3.5"
  DefaultTargets="Build"
  xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <ProductVersion>9.0.20726</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E0EA3EBA-718C-4122-B20C-EB97B7DC6604}</ProjectGuid>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <ProjectTypeGuids>
      {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};
      {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
    </ProjectTypeGuids>
  </PropertyGroup>
  ...
</Project>

Configurazione di compilazione

Un progetto Visual Studio predefinito possiede due configurazioni di compilazione: Debug e Release (vedere Configurazioni di compilazione). In un file di progetto MSBuild queste vengono configurate mediante proprietà:

<Project ... >
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">
      Debug
    </Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>WpfApplication1</RootNamespace>
    <AssemblyName>WpfApplication1</AssemblyName>
    <FileAlignment>512</FileAlignment>
    <WarningLevel>4</WarningLevel>
    ...
  </PropertyGroup>
  ...
</Project>

La configurazione di compilazione corrente è specificata dalla proprietà Configuration:

<Project ... >
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">
      Debug
    </Configuration>
    ...
  </PropertyGroup>
  ...
</Project>

Associazione dei file di codice sorgente

Visual Studio gestisce un'associazione tra i file di codice sorgente correlati, ad esempio i file di markup e code-behind. L'associazione può essere visualizzata nella finestra Esplora soluzioni di Visual Studio:

Schermata di Esplora soluzioni

L'associazione tra file di codice sorgente correlati viene realizzata utilizzando i metadati DependentUpon e SubType:

<Project ... >
  ...
  <ItemGroup>
    <ApplicationDefinition Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>
    <Page Include="Window1.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="App.xaml.cs">
      <DependentUpon>App.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Window1.xaml.cs">
      <DependentUpon>Window1.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
  </ItemGroup>
  ...
</Project>

In questo progetto, App.xaml (markup) è associato ad App.xaml.cs (code-behind), mentre Window1.xaml (markup) è associato a Window1.xaml.cs (code-behind).

Gestione di proprietà, risorse e impostazioni predefinite del progetto

Visual Studio consente di modificare visivamente le proprietà di un progetto Visual Studio. La maggior parte di queste influisce sul processo di compilazione e viene archiviata nel file di progetto Visual Studio gestito da Visual Studio. I modelli di progetto Windows Presentation Foundation (WPF) generano anche file per fornire un supporto per le risorse e le impostazioni fortemente tipizzate. Vedere in proposito la figura che segue:

Schermata di Esplora soluzioni

La gestione da parte del file di progetto MSBuild avviene tramite il seguente codice:

<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  ...
  <ItemGroup>
    <Compile Include="Properties\AssemblyInfo.cs">
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="Properties\Settings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
    <None Include="Properties\Settings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <AppDesigner Include="Properties\" />
  </ItemGroup>
  ...
</Project>

Compilazione di un progetto MSBuild per WPF

I progetti MSBuild possono essere compilati da un prompt dei comandi o da Visual Studio.

Compilazione di un progetto MSBuild per WPF dal prompt dei comandi

I progetti MSBuild possono essere compilati chiamando msbuild.exe dal prompt dei comandi di Windows o dal prompt dei comandi di Windows Software Development Kit (SDK).

Compilazione di un progetto

Per compilare un progetto MSBuild, eseguire msbuild.exe passando il nome file del progetto MSBuild desiderato:

msbuild.exe msbuildprojectfile.proj

Compilazione di un progetto specifico del linguaggio generato da Visual Studio

I file di progetto MSBuild specifici del linguaggio generati da Visual Studio:

  • Possiedono un'estensione di file pertinente (.csproj, .vbproj).

  • Includono una destinazione specifica del linguaggio (Microsoft.CSharp.targets, Microsoft.VisualBasic.targets).

Di seguito viene illustrato come compilare un progetto C# dal prompt dei comandi:

msbuild.exe VSGeneratedProjectFileForCSharp.csproj

Di seguito viene illustrato come compilare un progetto Visual Basic dal prompt dei comandi:

msbuild.exe VSGeneratedProjectFileForVisualBasic.vbproj

Compilazione di una soluzione generata da Visual Studio

msbuild.exe consente anche di compilare file di soluzione (.sln) generati da Visual Studio:

msbuild.exe VSGeneratedSolutionFile.sln

Compilazione di un progetto MSBuild per WPF in Visual Studio

In caso di utilizzo di Visual Studio, non è necessario compilare i progetti e le soluzioni dal prompt dei comandi. Visual Studio consente infatti di eseguire la compilazione dall'IDE.

Compilazione di un progetto in Visual Studio

Per compilare un progetto in Visual Studio, fare clic con il pulsante destro del mouse sul progetto nella finestra Esplora soluzioni e scegliere Compila.

Compilazione di una soluzione in Visual Studio

Per compilare una soluzione, effettuare una delle seguenti operazioni:

  • Premere F6 per compilare la soluzione.

  • Premere F5 per avviare il debug della soluzione.

  • Scegliere Compila | Compila soluzione.

  • Scegliere Debug | Avvia debug.

  • Scegliere Debug | Avvia senza eseguire debug.

Se si esegue una delle operazioni elencate per un progetto o una soluzione, Visual Studio esegue msbuild.exe per compilare i file MSBuild appropriati.

Pipeline di compilazione Windows Presentation Foundation

Quando si compila un progetto WPF vengono richiamate tutte le destinazioni specifiche del linguaggio e di WPF. Il processo di esecuzione di queste destinazioni viene definito pipeline di compilazione. Nella figura che segue vengono illustrati i principali passaggi che costituiscono tale processo.

Processo di compilazione WPF

Nelle sezioni che seguono è contenuta una descrizione più dettagliata di questi passaggi.

Inizializzazioni pre-compilazione

Prima della compilazione, MSBuild determina il percorso di strumenti e librerie importanti, tra cui:

  • .NET Framework.

  • Le directory Windows SDK.

  • Il percorso degli assembly di riferimento WPF.

  • La proprietà per i percorsi di ricerca degli assembly.

La directory degli assembly di riferimento (%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\) è il primo percorso in cui vengono cercati gli assembly. Durante questa fase, il processo di compilazione inizializza anche le varie proprietà e i gruppi di elementi ed esegue eventuali operazioni di pulitura necessarie.

Risoluzione dei riferimenti

Il processo di compilazione individua e associa gli assembly richiesti per compilare il progetto di applicazione. Questa logica è contenuta nell'attività ResolveAssemblyReference. Tutti gli assembly dichiarati come Reference nel file di progetto vengono forniti all'attività insieme alle informazioni sui percorsi di ricerca e ai metadati degli assembly già installati nel sistema. L'attività ricerca gli assembly e utilizza i metadati degli assembly installati per escludere gli assembly WPF di base che non devono essere visualizzati nei manifesti di output. In questo modo non vi saranno informazioni ridondanti nei manifesti ClickOnce. Ad esempio, dal momento che PresentationFramework.dll può essere considerato rappresentativo di un'applicazione compilata in e per WPF e tutti gli assembly WPF si trovano nello stesso percorso su ogni computer nel quale sia installato .NET Framework, non occorre includere tutte le informazioni su tutti gli assembly di riferimento .NET Framework nei manifesti.

Compilazione del markup – Passaggio 1

In questo passaggio i file XAML vengono analizzati e compilati, così che il runtime non dovrà analizzare XML né convalidare i valori delle proprietà. Il file XAML compilato viene presuddiviso in token, in modo tale da rendere molto più rapido il caricamento in fase di esecuzione.

Durante questo passaggio, per ogni file XAML che rappresenta un elemento di compilazione Page vengono eseguite le seguenti attività:

  1. Il file XAML viene analizzato dal compilatore di markup.

  2. Una rappresentazione compilata viene creata per il suddetto file XAML e copiata nella cartella obj\Release.

  3. Una rappresentazione CodeDOM di una nuova classe parziale viene creata e copiata nella cartella obj\Release.

Inoltre, per ogni file XAML viene generato un file di codice specifico del linguaggio. Ad esempio, per una pagina Page1.xaml in un progetto Visual Basic viene generato un file Page1.g.vb; per una pagina Page1.xaml in un progetto C# viene generato un file Page1.g.cs. Il componente ".g" nel nome del file indica la generazione di un file di codice avente una dichiarazione di classe parziale per l'elemento di primo livello del file di markup, quale ad esempio Page o Window. La classe viene dichiarata con il modificatore partial in C# e Extends in Visual Basic per indicare la presenza di un'altra dichiarazione di classe in un percorso diverso, generalmente nel file code-behind Page1.xaml.cs.

La classe parziale si estende dalla classe di base appropriata, ad esempio Page nel caso di una pagina, e implementa l'interfaccia System.Windows.Markup.IComponentConnector. L'interfaccia IComponentConnector possiede metodi che consentono di inizializzare un componente e connettere nomi ed eventi negli elementi del contenuto. Di conseguenza, l'implementazione dei metodi del file di codice generato sarà analoga alla seguente:

public void InitializeComponent() {
    if (_contentLoaded) {
        return;
    }
    _contentLoaded = true;
    System.Uri resourceLocater = 
        new System.Uri(
            "window1.xaml", 
            System.UriKind.RelativeOrAbsolute);
    System.Windows.Application.LoadComponent(this, resourceLocater);
}

Per impostazione predefinita, la compilazione del markup viene eseguita nello stesso oggetto AppDomain del motore MSBuild. In questo modo si ottengono notevoli miglioramenti delle prestazioni. Questo comportamento può essere modificato mediante la proprietà AlwaysCompileMarkupFilesInSeparateDomain. Tale proprietà offre il vantaggio di scaricare tutti gli assembly di riferimento scaricando l'oggetto AppDomain separato.

Compilazione del markup – Passaggio 2

Non tutte le pagine XAML vengono compilate durante il passaggio 1 della compilazione del markup. I file XAML con riferimenti a tipi definiti localmente, ossia definiti altrove nel codice all'interno dello stesso progetto, non vengono compilati durante questa fase. Questo avviene perché i tipi definiti localmente esistono soltanto nell'origine e non sono ancora stati compilati. Per determinare quanto detto il parser utilizza un'euristica che implica la ricerca di elementi, ad esempio x:Name, nel file di markup. Quando un'istanza di questo tipo viene trovata, la compilazione del file di markup viene posticipata fino all'avvenuta compilazione dei file di codice, i quali verranno successivamente elaborati nel secondo passaggio di compilazione del markup.

Classificazione dei file

Durante il processo di compilazione i file di output vengono inseriti in gruppi di risorse diversi, a seconda dell'assembly dell'applicazione in cui verranno collocati. In un'applicazione non localizzata tipica, tutti i file di dati contrassegnati come Resource vengono collocati nell'assembly principale (eseguibile o libreria). Quando si imposta UICulture nel progetto, tutti i file XAML compilati e le risorse specificatamente contrassegnate come specifiche della lingua vengono collocati nell'assembly di risorse satellite. Inoltre, tutte le risorse indipendenti dalla lingua vengono collocate nell'assembly principale. Questo passaggio del processo di compilazione comporta tale classificazione.

Le azioni di compilazione di ApplicationDefinition, Page e Resource nel file di progetto possono essere ampliate con i metadati Localizable, i cui valori accettabili sono true e false, che indicano se il file è specifico della lingua o indipendente dalla lingua.

Compilazione principale

Il passaggio principale della compilazione implica la compilazione dei file di codice. Tale operazione viene gestita dalla logica nei file delle destinazioni specifiche del linguaggio Microsoft.CSharp.targets e Microsoft.VisualBasic.targets. Se in base all'euristica è stato stabilito che sia sufficiente un unico passaggio del compilatore di markup, allora viene generato l'assembly principale. Tuttavia, se uno o più file XAML nel progetto possiedono riferimenti a tipi definiti localmente, viene generato un file DLL temporaneo e gli assembly finali dell'applicazione potranno essere creati una volta completato il secondo passaggio della compilazione del markup.

Generazione di manifesti

Al termine del processo di compilazione, una volta creati tutti gli assembly e i file di dati dell'applicazione, vengono generati i manifesti ClickOnce per l'applicazione.

Il file del manifesto di distribuzione descrive il modello di distribuzione, ovvero la versione corrente, il comportamento di aggiornamento e l'identità dell'editore insieme alla firma digitale. Questo manifesto deve essere creato dagli amministratori che gestiscono la distribuzione. L'estensione di file è xbap per le applicazione browser XAML (XBAP) e application per le applicazioni installate. La prima viene stabilita dalla proprietà del progetto HostInBrowser e, di conseguenza, il manifesto identifica l'applicazione come ospitata da browser.

Il manifesto dell'applicazione, un file con estensione exe.manifest, descrive gli assembly e le librerie dipendenti dell'applicazione ed elenca le autorizzazioni richieste dalla stessa. Questo file deve essere creato dallo sviluppatore di applicazioni. Per avviare un'applicazione ClickOnce, occorre aprire il file manifesto di distribuzione dell'applicazione.

Questi file manifesto vengono sempre creati per le applicazioni XBAP. Non vengono invece creati per le applicazioni installate, a meno che la proprietà GenerateManifests non sia specificata nel file di progetto con il valore true.

Le applicazioni XBAP ottengono due autorizzazioni aggiuntive oltre a quelle assegnate alle applicazioni dell'area Internet tipiche: WebBrowserPermission e MediaPermission. Il sistema di compilazione WPF dichiara le suddette autorizzazioni nel manifesto dell'applicazione.

Supporto per compilazioni incrementali

Il sistema di compilazione WPF fornisce un supporto per le compilazioni incrementali. Tale supporto consente di rilevare le modifiche apportate al markup o al codice e compilare soltanto gli elementi interessati dalle modifiche. Il meccanismo di compilazione incrementale utilizza i seguenti file:

  • Un file $(NomeAssembly)_MarkupCompiler.Cache per gestire lo stato del compilatore corrente.

  • Un file $(NomeAssembly)_MarkupCompiler.lref per memorizzare nella cache i file XAML con riferimenti a tipi definiti localmente.

Di seguito viene riportato un insieme di regole relative alla compilazione incrementale:

  • Il file è l'unità più piccola in cui il sistema di compilazione rileva le modifiche. Nel caso di un file di codice, pertanto, tale sistema non è in grado di rilevare la modifica di un tipo né l'aggiunta di codice. Lo stesso vale per i file di progetto.

  • Il meccanismo di compilazione incrementale deve tenere conto del fatto che una pagina XAML definisce una classe o utilizza altre classi.

  • Se le voci Reference vengono modificate, ricompilare tutte le pagine.

  • Se un file di codice viene modificato, ricompilare tutte le pagine con riferimenti a tipi definiti localmente.

  • Se un file XAML viene modificato:

    • Se il codice XAML è dichiarato come Page nel progetto: se il codice XAML non possiede riferimenti a tipi definiti localmente, ricompilare il codice e tutte le pagine XAML con riferimenti locali; se il codice XAML possiede riferimenti locali, ricompilare tutte le pagine XAML con riferimenti locali.

    • Se il codice XAML è dichiarato come ApplicationDefinition nel progetto: ricompilare tutte le pagine XAML, poiché ogni codice XAML possiede un riferimento a un tipo Application che può essere stato modificato.

  • Se il file di progetto dichiara un file di codice come definizione di applicazione anziché un file XAML:

    • Controllare se il valore di ApplicationClassName nel file di progetto è stato modificato, ovvero se è presente un nuovo tipo di applicazione. In caso affermativo, ricompilare l'intera applicazione.

    • In caso contrario, ricompilare tutte le pagine XAML con riferimenti locali.

  • Se un file di progetto viene modificato: applicare tutte le regole elencate in precedenza e stabilire gli elementi da ricompilare. Le modifiche alle seguenti proprietà comportano una ricompilazione totale: AssemblyName, IntermediateOutputPath, RootNamespace e HostInBrowser.

Di seguito vengono riportati i possibili scenari di ricompilazione:

  • Viene ricompilata l'intera applicazione.

  • Vengono ricompilati soltanto i file XAML con riferimenti a tipi definiti localmente.

  • Non avviene alcuna ricompilazione, in quanto il progetto non ha subito modifiche.

Vedere anche

Concetti

Distribuzione di un'applicazione WPF (WPF)

URI di tipo pack in Windows Presentation Foundation

File di dati e di risorse delle applicazioni Windows Presentation Foundation

Altre risorse

Riferimento a MSBuild di Windows Presentation Foundation

Cronologia delle modifiche

Date

History

Motivo

Luglio 2008

Informazioni aggiunte sulla proprietà di compilazione SplashScreen.

Modifica di funzionalità in SP1.