Bagikan melalui


Mengkompilasi Aplikasi WPF

Aplikasi Windows Presentation Foundation (WPF) dapat dibangun sebagai .NET Framework executables (.exe), pustaka (.dll), atau kombinasi dari kedua jenis rakitan. Topik ini memperkenalkan cara membangun aplikasi WPF dan menjelaskan langkah-langkah utama dalam proses build.

Membangun Aplikasi WPF

Aplikasi WPF dapat dikompilasi dengan cara berikut:

Alur Build WPF

Ketika proyek WPF dibangun, kombinasi target khusus bahasa dan khusus WPF dipanggil. Proses menjalankan target ini disebut alur build, dan langkah-langkah utama diilustrasikan oleh gambar berikut.

WPF build process

Inisialisasi Pra-Build

Sebelum membangun, MSBuild menentukan lokasi alat dan pustaka penting, termasuk yang berikut ini:

  • The .NET Framework.

  • Direktori Windows SDK.

  • Lokasi rakitan referensi WPF.

  • Properti untuk jalur pencarian rakitan.

Lokasi pertama tempat MSBuild mencari rakitan adalah direktori perakitan referensi (%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\). Selama langkah ini, proses build juga menginisialisasi berbagai properti dan grup item dan melakukan pekerjaan pembersihan yang diperlukan.

Mengatasi Referensi

Proses build menemukan dan mengikat rakitan yang diperlukan untuk membangun proyek aplikasi. Logika ini terkandung dalam ResolveAssemblyReference tugas. Semua rakitan yang dinyatakan sebagai Reference dalam file proyek disediakan untuk tugas bersama dengan informasi tentang jalur pencarian dan metadata pada rakitan yang sudah diinstal pada sistem. Tugas mencari rakitan dan menggunakan metadata rakitan yang diinstal untuk memfilter rakitan WPF inti yang tidak perlu muncul dalam manifes output. Ini dilakukan untuk menghindari informasi berlebihan dalam manifes ClickOnce. Misalnya, karena PresentationFramework.dll dapat dianggap sebagai perwakilan dari aplikasi yang dibangun di dan untuk WPF, dan karena semua rakitan WPF ada di lokasi yang sama pada setiap komputer yang menginstal .NET Framework, tidak perlu menyertakan semua informasi pada semua rakitan referensi .NET Framework dalam manifes.

Kompilasi Markup—Pass 1

Dalam langkah ini, file XAML diurai dan dikompilasi sehingga runtime tidak menghabiskan waktu mengurai XML dan memvalidasi nilai properti. File XAML yang dikompilasi telah ditokenisasi sebelumnya sehingga, pada waktu proses, memuatnya harus jauh lebih cepat daripada memuat file XAML.

Selama langkah ini, aktivitas berikut berlangsung untuk setiap file XAML yang merupakan Page item build:

  1. File XAML diurai oleh pengkompilasi markup.

  2. Representasi yang dikompilasi dibuat untuk XAML tersebut dan disalin ke folder obj\Release.

  3. Representasi CodeDOM dari kelas parsial baru dibuat dan disalin ke folder obj\Release.

Selain itu, file kode khusus bahasa dibuat untuk setiap file XAML. Misalnya, untuk halaman Page1.xaml dalam proyek Visual Basic, Page1.g.vb dihasilkan; untuk halaman Page1.xaml dalam proyek C#, Page1.g.cs dihasilkan. ".g" dalam nama file menunjukkan file dihasilkan kode yang memiliki deklarasi kelas parsial untuk elemen tingkat atas file markup (seperti Page atau Window). Kelas dinyatakan dengan partial pengubah di C# (Extends di Visual Basic) untuk menunjukkan ada deklarasi lain untuk kelas di tempat lain, biasanya dalam file code-behind Page1.xaml.cs.

Kelas parsial diperluas dari kelas dasar yang sesuai (seperti Page untuk halaman) dan mengimplementasikan System.Windows.Markup.IComponentConnector antarmuka. Antarmuka IComponentConnector memiliki metode untuk menginisialisasi komponen dan menghubungkan nama dan peristiwa pada elemen dalam kontennya. Akibatnya, file kode yang dihasilkan memiliki implementasi metode seperti berikut:

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);
}
Public Sub InitializeComponent() _

    If _contentLoaded Then
        Return
    End If

    _contentLoaded = True
    Dim resourceLocater As System.Uri = _
        New System.Uri("mainwindow.xaml", System.UriKind.Relative)

    System.Windows.Application.LoadComponent(Me, resourceLocater)

End Sub

Secara default, kompilasi markup berjalan sama dengan AppDomain mesin MSBuild. Ini memberikan keuntungan performa yang signifikan. Perilaku ini dapat diubah dengan AlwaysCompileMarkupFilesInSeparateDomain properti . Ini memiliki keuntungan untuk membongkar semua rakitan referensi dengan membongkar terpisah AppDomain.

Kompilasi Markup—Pass 2

Tidak semua halaman XAML dikompilasi pada selama lulus 1 kompilasi markup. File XAML yang memiliki referensi jenis yang ditentukan secara lokal (referensi ke jenis yang ditentukan dalam kode di tempat lain dalam proyek yang sama) dikecualikan dari kompilasi saat ini. Ini karena jenis yang ditentukan secara lokal hanya ada di sumber dan belum dikompilasi. Untuk menentukan hal ini, pengurai menggunakan heuristik yang melibatkan pencarian item seperti x:Name dalam file markup. Ketika instans seperti itu ditemukan, kompilasi file markup tersebut ditunda sampai file kode telah dikompilasi, setelah itu, kompilasi markup kedua memproses file-file ini.

Klasifikasi File

Proses build menempatkan file output ke dalam grup sumber daya yang berbeda berdasarkan perakitan aplikasi tempat mereka akan ditempatkan. Dalam aplikasi nonlokalisasi umum, semua file data yang ditandai sebagai Resource ditempatkan di rakitan utama (dapat dieksekusi atau pustaka). Ketika UICulture diatur dalam proyek, semua file XAML yang dikompilasi dan sumber daya yang secara khusus ditandai sebagai bahasa khusus ditempatkan di perakitan sumber daya satelit. Selain itu, semua sumber daya netral bahasa ditempatkan di perakitan utama. Dalam langkah proses build ini, penentuan tersebut dibuat.

ApplicationDefinitionTindakan build , Page, dan Resource dalam file proyek dapat ditambah dengan Localizable metadata (nilai yang dapat diterima adalah true dan false), yang menentukan apakah file spesifik bahasa atau bahasa netral.

Kompilasi Inti

Langkah kompilasi inti melibatkan kompilasi file kode. Ini diorkestrasi oleh logika dalam file target khusus bahasa Microsoft.CSharp.targets dan Microsoft.VisualBasic.targets. Jika heuristik telah menentukan bahwa satu pass kompilator markup sudah cukup, maka rakitan utama dihasilkan. Namun, jika satu atau beberapa file XAML dalam proyek memiliki referensi ke jenis yang ditentukan secara lokal, maka file .dll sementara dihasilkan sehingga rakitan aplikasi akhir dapat dibuat setelah lulus kedua kompilasi markup selesai.

Pembuatan Manifes

Di akhir proses build, setelah semua rakitan aplikasi dan file konten siap, manifes ClickOnce untuk aplikasi dibuat.

File manifes penyebaran menjelaskan model penyebaran: versi saat ini, perilaku pembaruan, dan identitas penerbit bersama dengan tanda tangan digital. Manifes ini dimaksudkan untuk ditulis oleh administrator yang menangani penyebaran. Ekstensi file adalah .xbap (untuk aplikasi browser XAML (XBAP)) dan .application untuk aplikasi yang diinstal. Yang pertama ditentukan oleh HostInBrowser properti proyek dan sebagai hasilnya manifes mengidentifikasi aplikasi sebagai browser yang dihosting.

Manifes aplikasi (file .exe.manifest) menjelaskan rakitan aplikasi dan pustaka dependen dan mencantumkan izin yang diperlukan oleh aplikasi. File ini dimaksudkan untuk ditulis oleh pengembang aplikasi. Untuk meluncurkan aplikasi ClickOnce, pengguna membuka file manifes penyebaran aplikasi.

File manifes ini selalu dibuat untuk XBAP. Untuk aplikasi yang diinstal, aplikasi tersebut tidak dibuat kecuali GenerateManifests properti ditentukan dalam file proyek dengan nilai true.

XBAP mendapatkan dua izin tambahan melalui dan di atas izin yang ditetapkan ke aplikasi zona Internet umum: WebBrowserPermission dan MediaPermission. Sistem build WPF mendeklarasikan izin tersebut dalam manifes aplikasi.

Dukungan Build Inkremental

Sistem build WPF menyediakan dukungan untuk build inkremental. Cukup cerdas tentang mendeteksi perubahan yang dilakukan pada markup atau kode, dan hanya mengkompilasi artefak yang terpengaruh oleh perubahan. Mekanisme build inkremental menggunakan file berikut:

  • File $(AssemblyName)_MarkupCompiler.Cache untuk mempertahankan status pengkompilasi saat ini.

  • File $(AssemblyName)_MarkupCompiler.lref untuk menyimpan file XAML dengan referensi ke jenis yang ditentukan secara lokal.

Berikut ini adalah sekumpulan aturan yang mengatur build inkremental:

  • File adalah unit terkecil di mana sistem build mendeteksi perubahan. Jadi, untuk file kode, sistem build tidak dapat mengetahui apakah jenis diubah atau jika kode ditambahkan. Penahanan yang sama untuk file proyek.

  • Mekanisme build inkremental harus kognizan bahwa halaman XAML mendefinisikan kelas atau menggunakan kelas lain.

  • Jika Reference entri berubah, maka kompilasi ulang semua halaman.

  • Jika file kode berubah, kompilasi ulang semua halaman dengan referensi jenis yang ditentukan secara lokal.

  • Jika file XAML berubah:

    • Jika XAML dinyatakan seperti Page dalam proyek: jika XAML tidak memiliki referensi jenis yang ditentukan secara lokal, kompilasi ulang bahwa XAML ditambah semua halaman XAML dengan referensi lokal; jika XAML memiliki referensi lokal, kompilasi ulang semua halaman XAML dengan referensi lokal.

    • Jika XAML dinyatakan seperti ApplicationDefinition dalam proyek: kompilasi ulang semua halaman XAML (alasan: setiap XAML memiliki referensi ke Application jenis yang mungkin telah berubah).

  • Jika file proyek mendeklarasikan file kode sebagai definisi aplikasi, bukan file XAML:

    • Periksa apakah ApplicationClassName nilai dalam file proyek telah berubah (apakah ada jenis aplikasi baru?). Jika demikian, kompilasi ulang seluruh aplikasi.

    • Jika tidak, kompilasi ulang semua halaman XAML dengan referensi lokal.

  • Jika file proyek berubah: terapkan semua aturan sebelumnya dan lihat apa yang perlu dikompresi ulang. Perubahan pada properti berikut memicu kompilasi ulang lengkap: AssemblyName, , IntermediateOutputPathRootNamespace, dan HostInBrowser.

Skenario kompilasi ulang berikut dimungkinkan:

  • Seluruh aplikasi dikompresi ulang.

  • Hanya file XAML yang memiliki referensi jenis yang ditentukan secara lokal yang dikompresi ulang.

  • Tidak ada yang dikompresi ulang (jika tidak ada dalam proyek yang berubah).

Baca juga