Bagikan melalui


Cara menampilkan status printer di aplikasi perangkat UWP

Important

Metadata perangkat tidak digunakan lagi dan akan dihapus dalam rilis Windows mendatang. Untuk informasi tentang penggantian fungsionalitas ini, lihat Metadata Kontainer Paket Driver.

Di Windows 8.1, pengguna dapat memeriksa status printer mereka dari UI modern aplikasi perangkat UWP. Topik ini menggunakan versi C# dari sampel Pengaturan cetak dan pemberitahuan cetak untuk menunjukkan cara mengkueri status printer dan menampilkannya. Untuk mempelajari selengkapnya tentang aplikasi perangkat UWP secara umum, lihat Mengenal aplikasi perangkat UWP.

Versi C# dari sampel Pengaturan cetak dan pemberitahuan cetak menggunakan halaman InkLevel.xaml untuk menunjukkan cara mendapatkan status printer (dalam hal ini, tingkat tinta) dan menampilkannya. Kelas pembantu cetak digunakan untuk membuat konteks perangkat (IPrinterExtensionContext) dan melakukan kueri perangkat. The PrinterHelperClass.cs file is in the DeviceAppForPrintersLibrary project and uses APIs defined in the PrinterExtensionLibrary project. Pustaka ekstensi printer menyediakan cara mudah untuk mengakses antarmuka ekstensi printer dari pengandar cetak v4. Untuk informasi selengkapnya, lihat Gambaran umum pustaka ekstensi Printer.

Note

Contoh kode yang ditampilkan dalam topik ini didasarkan pada versi C# dari sampel pengaturan Cetak dan pemberitahuan cetak . Sampel ini juga tersedia di JavaScript dan C++. Perhatikan bahwa karena C++ dapat mengakses COM secara langsung, versi C++ sampel tidak menyertakan proyek pustaka kode. Unduh sampel untuk melihat versi terbaru kode.

Prerequisites

Sebelum Anda memulai:

  1. Pastikan pencetak Anda terinstal menggunakan pengandar cetak v4. Untuk informasi selengkapnya, lihat Mengembangkan driver cetak v4.

  2. Siapkan PC pengembangan Anda. See Getting started for info about downloading the tools and creating a developer account.

  3. Kaitkan aplikasi Anda dengan toko. Lihat Langkah 1: Membuat aplikasi perangkat UWP untuk informasi tentang hal tersebut.

  4. Buat metadata perangkat untuk printer Anda yang mengaitkannya dengan aplikasi Anda. Lihat Langkah 2: Membuat metadata perangkat untuk informasi selengkapnya tentang hal tersebut.

  5. If you're writing your app with C# or JavaScript, add the PrinterExtensionLibrary and DeviceAppForPrintersLibrary projects to your UWP device app solution. Anda dapat menemukan masing-masing proyek ini di pengaturan Cetak dan sampel pemberitahuan cetak .

    Note

    Karena C++ dapat mengakses COM secara langsung, aplikasi C++ tidak memerlukan pustaka terpisah untuk bekerja dengan konteks perangkat printer berbasis COM.

Langkah 1: Temukan printer

Sebelum konteks perangkat dapat dibuat, aplikasi perlu menentukan ID perangkat printer. Untuk melakukan ini, sampel menggunakan EnumerateAssociatedPrinters metode untuk mencari melalui semua printer yang terpasang pada PC. Kemudian memeriksa kontainer untuk setiap printer dan mencari asosiasi dengan membandingkan properti PackageFamilyName setiap kontainer.

Note

The System.Devices.AppPackageFamilyName for devices that are associated with your app can be found under the Packaging tab on the Manifest Designer in Microsoft Visual Studio.

This example shows the EnumerateAssociatedPrinters method from the InkLevel.xaml.cs file:

async void EnumerateAssociatedPrinters(object sender, RoutedEventArgs e)
{
    // Reset output text and associated printer array.
    AssociatedPrinters.Items.Clear();
    BidiOutput.Text = "";

    // GUID string for printers.
    string printerInterfaceClass = "{0ecef634-6ef0-472a-8085-5ad023ecbccd}";
    string selector = "System.Devices.InterfaceClassGuid:=\"" + printerInterfaceClass + "\"";

    // By default, FindAllAsync does not return the containerId for the device it queries.
    // We have to add it as an additional property to retrieve. 
    string containerIdField = "System.Devices.ContainerId";
    string[] propertiesToRetrieve = new string[] { containerIdField };

    // Asynchronously find all printer devices.
    DeviceInformationCollection deviceInfoCollection = await DeviceInformation.FindAllAsync(selector, propertiesToRetrieve);

    // For each printer device returned, check if it is associated with the current app.
    for (int i = 0; i < deviceInfoCollection.Count; i++)
    {
        DeviceInformation deviceInfo = deviceInfoCollection[i];
        FindAssociation(deviceInfo, deviceInfo.Properties[containerIdField].ToString());
    }
}

Metode FindAssociation , yang dipanggil oleh EnumerateAssociatedPrinters, memeriksa apakah printer terkait dengan aplikasi saat ini. Dengan kata lain, metode ini memeriksa apakah aplikasi tersebut adalah aplikasi perangkat UWP. Asosiasi ini ada ketika aplikasi dan printer didefinisikan dalam metadata perangkat pada PC lokal.

This example shows the FindAssociation method from the InkLevel.xaml.cs file:

async void FindAssociation(DeviceInformation deviceInfo, string containerId)
{

    // Specifically telling CreateFromIdAsync to retrieve the AppPackageFamilyName. 
    string packageFamilyName = "System.Devices.AppPackageFamilyName";
    string[] containerPropertiesToGet = new string[] { packageFamilyName };

    // CreateFromIdAsync needs braces on the containerId string.
    string containerIdwithBraces = "{" + containerId + "}";

    // Asynchronously getting the container information of the printer.
    PnpObject containerInfo = await PnpObject.CreateFromIdAsync(PnpObjectType.DeviceContainer, containerIdwithBraces, containerPropertiesToGet);

    // Printers could be associated with other device apps, only the ones with package family name
    // matching this app's is associated with this app. The packageFamilyName for this app will be found in this app's packagemanifest
    string appPackageFamilyName = "Microsoft.SDKSamples.DeviceAppForPrinters.CS_8wekyb3d8bbwe";
    var prop = containerInfo.Properties;

    // If the packageFamilyName of the printer container matches the one for this app, the printer is associated with this app.
    string[] packageFamilyNameList = (string[])prop[packageFamilyName];
    if (packageFamilyNameList != null)
    {
        for (int j = 0; j < packageFamilyNameList.Length; j++)
        {
            if (packageFamilyNameList[j].Equals(appPackageFamilyName))
            {
                AddToList(deviceInfo);
            }
        }
    }
}

Ketika asosiasi ditemukan, FindAssociation metode menggunakan AddToList metode untuk menambahkan ID perangkat ke daftar ID perangkat terkait. ID ini disimpan dalam ComboBox bernama AssociatedPrinters.

This example shows the AddToList method from the InkLevel.xaml.cs file:

void AddToList(DeviceInformation deviceInfo)
{
    // Creating a new display item so the user sees the friendly name instead of the interfaceId.
    ComboBoxItem item = new ComboBoxItem();
    item.Content = deviceInfo.Properties["System.ItemNameDisplay"] as string;
    item.DataContext = deviceInfo.Id;
    AssociatedPrinters.Items.Add(item);

    // If this is the first printer to be added to the combo box, select it.
    if (AssociatedPrinters.Items.Count == 1)
    {
        AssociatedPrinters.SelectedIndex = 0;
    }
}

Langkah 2: Menampilkan status

Metode ini GetInkStatus menggunakan pola berbasis peristiwa asinkron untuk meminta informasi dari printer. Metode ini menggunakan ID perangkat terkait untuk mendapatkan konteks perangkat yang dapat digunakan untuk mendapatkan status perangkat. Pemanggilan metode printHelper.SendInkLevelQuery() memulai kueri perangkat. Ketika respons kembali, OnInkLevelReceived metode dipanggil dan UI diperbarui.

Note

Contoh C# ini mengikuti pola yang berbeda dari sampel JavaScript, karena C# memungkinkan Anda mengirim dispatcher ke PrintHelperClass sehingga dapat memposting pesan peristiwa kembali ke utas UI.

This example shows the GetInkStatus and OnInkLevelReceived methods from the InkLevel.xaml.cs file:

void GetInkStatus(object sender, RoutedEventArgs e)
{
    if (AssociatedPrinters.Items.Count > 0)
    {
        // Get the printer that the user has selected to query.
        ComboBoxItem selectedItem = AssociatedPrinters.SelectedItem as ComboBoxItem;

        // The interfaceId is retrieved from the detail field.
        string interfaceId = selectedItem.DataContext as string;

        try
        {
            // Unsubscribe existing ink level event handler, if any.
            if (printHelper != null)
            {
                printHelper.OnInkLevelReceived -= OnInkLevelReceived;
                printHelper = null;
            }

            object context = Windows.Devices.Printers.Extensions.PrintExtensionContext.FromDeviceId(interfaceId);printHelper.SendInkLevelQuery()

            // Use the PrinterHelperClass to retrieve the bidi data and display it.
            printHelper = new PrintHelperClass(context);
            try
            {
                printHelper.OnInkLevelReceived += OnInkLevelReceived;
                printHelper.SendInkLevelQuery();

                rootPage.NotifyUser("Ink level query successful", NotifyType.StatusMessage);
            }
            catch (Exception)
            {
                rootPage.NotifyUser("Ink level query unsuccessful", NotifyType.ErrorMessage);
            }
        }
        catch (Exception)
        {
            rootPage.NotifyUser("Error retrieving PrinterExtensionContext from InterfaceId", NotifyType.ErrorMessage);
        }
    }
}

private void OnInkLevelReceived(object sender, string response)
{
    BidiOutput.Text = response;
}

Kelas pembantu cetak mengurus pengiriman kueri Bidi ke perangkat dan menerima respons.

This example shows the SendInkLevelQuery method, and others, from the PrintHelperClass.cs file. Perhatikan bahwa hanya beberapa metode kelas pembantu cetak yang ditampilkan di sini. Unduh sampel Pengaturan cetak dan pemberitahuan cetak untuk melihat kode lengkap.

public void SendInkLevelQuery()
{
    printerQueue.OnBidiResponseReceived += OnBidiResponseReceived;

    // Send the query.
    string queryString = "\\Printer.Consumables";
    printerQueue.SendBidiQuery(queryString);
}

private void OnBidiResponseReceived(object sender, PrinterQueueEventArgs responseArguments)
{
    // Invoke the ink level event with appropriate data.
    dispatcher.RunAsync(
        Windows.UI.Core.CoreDispatcherPriority.Normal,
        () =>
        {
            OnInkLevelReceived(sender, ParseResponse(responseArguments));
        });
}

private string ParseResponse(PrinterQueueEventArgs responseArguments)
{
    if (responseArguments.StatusHResult == (int)HRESULT.S_OK)
        return responseArguments.Response;
    else
        return InvalidHResult(responseArguments.StatusHResult);
}

private string InvalidHResult(int result)
{
    switch (result)
    {
        case unchecked((int)HRESULT.E_INVALIDARG):
            return "Invalid Arguments";
        case unchecked((int)HRESULT.E_OUTOFMEMORY):
            return "Out of Memory";
        case unchecked((int)HRESULT.ERROR_NOT_FOUND):
            return "Not found";
        case (int)HRESULT.S_FALSE:
            return "False";
        case (int)HRESULT.S_PT_NO_CONFLICT:
            return "PT No Conflict";
        default:
            return "Undefined status: 0x" + result.ToString("X");
    }
}

Testing

Sebelum dapat menguji aplikasi perangkat UWP, aplikasi tersebut harus ditautkan ke printer Anda menggunakan metadata perangkat.

Anda memerlukan salinan paket metadata perangkat untuk printer Anda, untuk menambahkan info aplikasi perangkat ke dalamnya. Jika Anda tidak memiliki metadata perangkat, Anda dapat membuatnya menggunakan Wizard Penulisan Metadata Perangkat seperti yang dijelaskan dalam topik Langkah 2: Membuat metadata perangkat untuk aplikasi perangkat UWP Anda.

Note

Untuk menggunakan Wizard Penulisan Metadata Perangkat, Anda harus menginstal Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate, atau SDK mandiri untuk Windows 8.1, sebelum menyelesaikan langkah-langkah dalam topik ini. Menginstal Microsoft Visual Studio Express untuk Windows menginstal versi SDK yang tidak menyertakan wizard.

Langkah-langkah berikut membuat aplikasi Anda dan menginstal metadata perangkat.

  1. Aktifkan tanda tangan uji.

    1. Mulai Wizard Penulisan Metadata Perangkat dari %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 dengan klik dua kali pada DeviceMetadataWizard.exe.

    2. From the Tools menu, select Enable Test Signing.

  2. Mulai ulang komputer

  3. Bangun solusi dengan membuka file solusi (.sln). Tekan F7 atau buka > dari menu atas setelah contoh selesai dimuat.

  4. Putuskan sambungan dan copot pemasangan printer. Langkah ini diperlukan agar Windows akan membaca metadata perangkat yang diperbarui saat perangkat terdeteksi berikutnya.

  5. Edit dan simpan metadata perangkat. Untuk menautkan aplikasi perangkat ke perangkat, Anda harus mengaitkan aplikasi perangkat dengan perangkat Anda.

    Note

    Jika Anda belum membuat metadata perangkat, lihat Langkah 2: Membuat metadata perangkat untuk aplikasi perangkat UWP Anda.

    1. Jika Wizard Penulisan Metadata Perangkat belum dibuka, mulai dari %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, dengan mengklik dua kali DeviceMetadataWizard.exe.

    2. Klik Edit Perangkat Metadata. Ini akan memungkinkan Anda mengedit paket metadata perangkat yang ada.

    3. In the Open dialog box, locate the device metadata package associated with your UWP device app. (It has a devicemetadata-ms file extension.)

    4. Pada halaman Tentukan informasi aplikasi perangkat UWP , masukkan info aplikasi Microsoft Store di kotak aplikasi perangkat UWP . Klik Impor file manifes aplikasi UWP untuk secara otomatis memasukkan nama Paket , nama penerbit , dan ID aplikasi UWP .

    5. If your app is registering for printer notifications, fill out the Notification handlers box. In Event ID, enter the name of the print event handler. In Event Asset, enter the name of the file where that code resides.

    6. When you're done, click Next until you get to the Finish page.

    7. Pada halaman Tinjau paket metadata perangkat , pastikan semua pengaturan sudah benar dan pilih kotak centang Salin paket metadata perangkat ke penyimpanan metadata di komputer lokal . Then click Save.

  6. Sambungkan kembali pencetak Anda agar Windows membaca metadata perangkat yang diperbarui ketika perangkat tersambung.

Troubleshooting

Masalah: Tidak dapat menemukan printer saat menghitung perangkat yang terkait dengan aplikasi

Jika printer Anda tidak ditemukan saat menghitung printer terkait:

  • Possible cause: Test signing is not turned on. Lihat bagian Debugging dalam topik ini untuk informasi tentang mengaktifkannya.

  • Possible cause: The app is not querying for the right Package Family Name. Periksa Nama Keluarga Paket dalam kode Anda. Open up package.appxmanifest in Microsoft Visual Studio and make sure that the package family name you are querying for matches the one in the Packaging tab, in the Package Family Name field.

  • Possible cause: The device metadata is not associated with the Package Family Name. Gunakan Wizard Penulisan Metadata Perangkat untuk membuka metadata perangkat dan periksa nama keluarga paket. Start the wizard from %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, by double-clicking DeviceMetadataWizard.exe.

Masalah: Menemukan printer yang terkait dengan aplikasi, tetapi tidak dapat meminta informasi Bidi.

Jika printer Anda ditemukan saat mendata printer terkait, tetapi kueri Bidi mengembalikan kesalahan...

  • Possible cause: Wrong package family name. Periksa Nama Keluarga Paket dalam kode Anda. Open up package.appxmanifest in Visual Studio and make sure that the package family name you are querying for matches the one in the Packaging tab, in the Package Family Name field.

  • Possible cause: Printer was installed using a v3 printer, rather than a v4 printer. Untuk melihat versi mana yang diinstal, buka PowerShell dan ketik perintah berikut:

    get-printer | Select Name, {(get-printerdriver -Name $_.DriverName).MajorVersion}