Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Important
Geräte-Metadaten sind veraltet und werden in einer zukünftigen Version von Windows entfernt. Informationen zum Ersatz dieser Funktionalität finden Sie unter Treiberpaketcontainermetadaten.
In Windows 8.1 können Benutzer ihren Druckerstatus über die moderne Benutzeroberfläche einer UWP-Geräte-App überprüfen. In diesem Thema wird die C#-Version der Druckeinstellungen und des Druckbenachrichtigungsbeispiels verwendet, um zu veranschaulichen, wie sie den Druckerstatus abfragen und anzeigen. Weitere Informationen zu UWP-Geräte-Apps im Allgemeinen finden Sie unter "Treffen von UWP-Geräte-Apps".
In der C#-Version der Druckeinstellungen und des Druckbenachrichtigungsbeispiels wird die Seite "InkLevel.xaml " verwendet, um zu veranschaulichen, wie der Druckerstatus (in diesem Fall die Freihandebene) abgerufen und angezeigt wird. Eine Druckhilfsklasse wird verwendet, um einen Gerätekontext (IPrinterExtensionContext) zu erstellen und die Geräteabfragen auszuführen. The PrinterHelperClass.cs file is in the DeviceAppForPrintersLibrary project and uses APIs defined in the PrinterExtensionLibrary project. Die Druckererweiterungsbibliothek bietet eine bequeme Möglichkeit, auf die Druckererweiterungsschnittstellen des v4-Drucktreibers zuzugreifen. Weitere Informationen finden Sie in der Übersicht über die Druckererweiterungsbibliothek.
Note
Die in diesem Thema gezeigten Codebeispiele basieren auf der C#-Version der Druckeinstellungen und des Druckbenachrichtigungsbeispiels . Dieses Beispiel ist auch in JavaScript und C++ verfügbar. Da C++ direkt auf COM zugreifen kann, enthält die C++-Version des Beispiels keine Codebibliotheksprojekte. Laden Sie die Beispiele herunter, um die neuesten Versionen des Codes anzuzeigen.
Prerequisites
Bevor Sie beginnen:
Stellen Sie sicher, dass Ihr Drucker mit einem v4-Drucktreiber installiert ist. Weitere Informationen finden Sie unter Entwickeln von v4-Drucktreibern.
Richten Sie Ihren Entwicklungs-PC ein. See Getting started for info about downloading the tools and creating a developer account.
Ordnen Sie Ihre App dem Store zu. Informationen hierzu finden Sie in Schritt 1: Erstellen einer UWP-Geräte-App .
Erstellen Sie Gerätemetadaten für Ihren Drucker, der sie Ihrer App zuordnet. Weitere Informationen hierzu finden Sie in Schritt 2: Erstellen von Gerätemetadaten .
If you're writing your app with C# or JavaScript, add the PrinterExtensionLibrary and DeviceAppForPrintersLibrary projects to your UWP device app solution. Sie finden jedes dieser Projekte im Beispiel " Druckeinstellungen" und "Druckbenachrichtigungen" .
Note
Da C++ direkt auf COM zugreifen kann, benötigen C++-Apps keine separate Bibliothek, um mit dem COM-basierten Druckergerätekontext zu arbeiten.
Schritt 1: Suchen des Druckers
Bevor ein Gerätekontext erstellt werden kann, muss die App die Geräte-ID des Druckers ermitteln. Dazu verwendet das Beispiel die EnumerateAssociatedPrinters Methode, um alle Drucker zu durchsuchen, die an den PC angeschlossen sind. Anschließend überprüft er den Container für jeden Drucker und sucht nach einer Zuordnung, indem die PackageFamilyName-Eigenschaft jedes Containers verglichen wird.
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());
}
}
Die FindAssociation methode, aufgerufen von EnumerateAssociatedPrinters, überprüft, ob ein Drucker der aktuellen Anwendung zugeordnet ist. Mit anderen Worten: Diese Methode überprüft, ob es sich bei der App um eine UWP-Geräte-App handelt. Diese Zuordnung ist vorhanden, wenn die App und der Drucker in Gerätemetadaten auf dem lokalen PC definiert sind.
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);
}
}
}
}
Wenn eine Zuordnung gefunden wird, verwendet die Methode die FindAssociationAddToList Methode, um die Geräte-ID einer Liste der zugeordneten Geräte-IDs hinzuzufügen. Diese IDs werden in einem ComboBox-Steuerelement mit dem Namen AssociatedPrintersgespeichert.
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;
}
}
Schritt 2: Anzeigen des Status
Die GetInkStatus Methode verwendet ein asynchrones ereignisbasiertes Muster, um Informationen vom Drucker anzufordern. Diese Methode verwendet eine zugeordnete Geräte-ID, um einen Gerätekontext abzurufen, der zum Abrufen des Gerätestatus verwendet werden kann. Der Aufruf der printHelper.SendInkLevelQuery() Methode initiiert die Geräteabfrage. Wenn die Antwort zurückgegeben wird, wird die OnInkLevelReceived Methode aufgerufen, und die Benutzeroberfläche wird aktualisiert.
Note
Dieses C#-Beispiel folgt einem anderen Muster als dem JavaScript-Beispiel, da C# es Ihnen ermöglicht, einen Verteiler an die PrintHelperClass zu senden, damit die Ereignismeldungen wieder im UI-Thread gesendet werden können.
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;
}
Die Druckhilfsklasse kümmert sich um das Senden der Bidi-Abfrage an das Gerät und den Empfang der Antwort.
This example shows the SendInkLevelQuery method, and others, from the PrintHelperClass.cs file. Beachten Sie, dass hier nur einige der Druckhilfsklassenmethoden angezeigt werden. Laden Sie das Beispiel für Druckeinstellungen und Druckbenachrichtigungen herunter, um den vollständigen Code anzuzeigen.
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
Bevor Sie Ihre UWP-Geräte-App testen können, muss sie mithilfe von Gerätemetadaten mit Ihrem Drucker verknüpft werden.
Sie benötigen eine Kopie des Gerätemetadatenpakets für Ihren Drucker, um die Geräte-App-Informationen hinzuzufügen. Wenn Sie nicht über Gerätemetadaten verfügen, können Sie sie mit dem Assistenten für die Erstellung von Gerätemetadaten erstellen, wie im Thema Schritt 2 beschrieben: Erstellen von Gerätemetadaten für Ihre UWP-Geräte-App.
Note
Um den Assistenten zum Erstellen von Gerätemetadaten zu verwenden, müssen Sie Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate oder das eigenständige SDK für Windows 8.1 installieren, bevor Sie die Schritte in diesem Thema ausführen. Beim Installieren von Microsoft Visual Studio Express für Windows wird eine Version des SDK installiert, die den Assistenten nicht enthält.
Die folgenden Schritte erstellen Ihre App und installieren die Gerätemetadaten.
Aktivieren Sie die Testsignatur.
Starten Sie den Assistenten für die Erstellung von Gerätemetadaten aus %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exe doppelklicken.
From the Tools menu, select Enable Test Signing.
Neustarten des Computers
Erstellen Sie die Lösung, indem Sie die Lösungsdatei (.sln) öffnen. Drücken Sie F7 oder gehen Sie im oberen Menü zu Build->Build Solution, nachdem das Beispiel geladen wurde.
Trennen Sie den Drucker und deinstallieren Sie ihn. Dieser Schritt ist erforderlich, damit Windows die aktualisierten Gerätemetadaten beim nächsten Erkennen des Geräts liest.
Bearbeiten und Speichern von Gerätemetadaten Um die Geräte-App mit Ihrem Gerät zu verknüpfen, müssen Sie die Geräte-App Ihrem Gerät zuordnen.
Note
Wenn Sie Ihre Gerätemetadaten noch nicht erstellt haben, lesen Sie Schritt 2: Erstellen von Gerätemetadaten für Ihre UWP-Geräte-App.
Wenn der Assistent für die Erstellung von Gerätemetadaten noch nicht geöffnet ist, starten Sie ihn von %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, indem Sie auf DeviceMetadataWizard.exedoppelklicken.
Klicken Sie auf "Gerätemetadaten bearbeiten". Dadurch können Sie Ihr vorhandenes Gerätemetadatenpaket bearbeiten.
In the Open dialog box, locate the device metadata package associated with your UWP device app. (It has a devicemetadata-ms file extension.)
Geben Sie auf der Seite " Informationen zur UWP-Geräte-App angeben " die Informationen zur Microsoft Store-App in das Feld "UWP-Geräte-App " ein. Klicken Sie auf "UWP-App-Manifestdatei importieren", um automatisch den Paketnamen, den Herausgebernamen und die UWP-App-ID einzugeben.
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.
When you're done, click Next until you get to the Finish page.
Vergewissern Sie sich auf der Seite " Überprüfen des Gerätemetadatenpakets ", dass alle Einstellungen korrekt sind, und aktivieren Sie das Kontrollkästchen "Gerätemetadatenpaket in den Metadatenspeicher auf dem lokalen Computer kopieren ". Then click Save.
Verbinden Sie den Drucker erneut, damit Windows die aktualisierten Gerätemetadaten liest, wenn das Gerät verbunden ist.
Troubleshooting
Problem: Drucker beim Aufzählen von Geräten, die der App zugeordnet sind, können nicht gefunden werden
Wenn Ihr Drucker beim Aufzählen der zugehörigen Drucker nicht gefunden wird:
Possible cause: Test signing is not turned on. Informationen zum Aktivieren finden Sie im Abschnitt "Debuggen" in diesem Thema.
Possible cause: The app is not querying for the right Package Family Name. Überprüfen Sie den Paketfamiliennamen in Ihrem Code. 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. Verwenden Sie den Assistenten zum Erstellen von Gerätemetadaten , um die Gerätemetadaten zu öffnen und den Paketfamiliennamen zu überprüfen. Start the wizard from %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, by double-clicking DeviceMetadataWizard.exe.
Problem: Der der App zugeordnete Drucker wurde gefunden, kann aber keine Bidi-Informationen abfragen.
Wenn ihr Drucker beim Aufzählen der zugeordneten Drucker gefunden wurde, aber eine Bidi-Abfrage einen Fehler zurückgibt...
Possible cause: Wrong package family name. Überprüfen Sie den Paketfamiliennamen in Ihrem Code. 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. Um zu sehen, welche Version installiert ist, öffnen Sie PowerShell, und geben Sie den folgenden Befehl ein:
get-printer | Select Name, {(get-printerdriver -Name $_.DriverName).MajorVersion}