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.
Paketidentität ist ein eindeutiger Bezeichner über Raum und Zeit hinweg. Genau wie Ihre DNA Sie eindeutig identifiziert, identifiziert die Paketidentität ein Paket eindeutig.
Ein Paket verfügt über einen zugeordneten Satz von Bits (Dateien usw.). Keine zwei Pakete weisen dieselbe Identität auf, und alle Änderungen an den Bits, die einem Paket zugeordnet sind, erfordern eine andere Identität.
Was ist die Paketidentität?
Eine Paketidentität ist ein logisches Konstrukt, das ein Paket eindeutig identifiziert. Die Identität weist fünf Teile auf:
- Name: Dies ist ein Name, der vom App-Entwickler ausgewählt wird. Der Microsoft Store erzwingt die Eindeutigkeit aller App-Namen für alle App-Entwickler im Store, aber namen sind nicht garantiert im allgemeinen Ökosystem eindeutig.
- Version: Versionsnummer des Pakets. Der App-Entwickler kann beliebige Versionsnummern auswählen, muss jedoch sicherstellen, dass die Versionsnummern mit Updates steigen.
- Architektur: Die Prozessorarchitektur, auf die das Paket ausgerichtet wird. Dieselbe App kann für unterschiedliche Prozessorarchitekturen erstellt werden, wobei jedes Build in seinem eigenen Paket gespeichert wird.
-
ResourceId: Eine Zeichenfolge, die vom App-Entwickler ausgewählt wurde, um Ressourcenpakete eindeutig zu identifizieren, z. B. verschiedene Sprachen oder unterschiedliche Anzeigeskalen. Ressourcenpakete sind in der Regel architekturneutral. Bei Bündeln ist die ResourceId immer
~
. - Publisher: Der Subjektname des App-Entwicklers, der in ihrem Signaturzertifikat angegeben ist. Dies ist theoretisch für jeden App-Entwickler einzigartig, da seriöse Zertifizierungsstellen eindeutige reale Namen und Identitäten verwenden, um das Feld für den Namen des Antragstellers im Zertifikat zu füllen.
Dieses Konstrukt wird manchmal als 5-Part-Tupelbezeichnet.
Hinweis
Nicht signierte Pakete (1) erfordern weiterhin einen Herausgeber, (2) der Herausgeber muss den nicht signierten Marker (OID.2.25.311729368913984317654407730594956997722=1) enthalten, (3) die Markierung "Nicht signiert" muss das letzte Feld in der Herausgeber- Zeichenfolge sein, und (4) es gibt kein Zertifikat und keine Signatur für ein nicht signiertes Paket.
Grenzwerte für Paketidentitätsfelder
Feld | Datentyp | Grenzen | Kommentare |
---|---|---|---|
Name | Paketzeichenfolge | Min: 3 Max: 50 |
Zulässige Werte pro Validate-API (siehe Paketzeichenfolge) |
Version | DotQuad | Min: 0.0.0.0 Max: 65535.65535.65535.65535 |
Zeichenfolgenformat verwendet die Base-10-Punktnotation „Major.Minor.Build.Revision“. |
Architektur | Aufzählung | Min: N/A Max: N/A |
Zulässige Werte sind "neutral", "x86", "x64", "arm", "arm64", "x86a64" |
RessourcenID | Paketzeichenfolge | Min: 0 Max: 30 |
Zulässige Werte pro Validate-API (siehe Paketzeichenfolge) |
Herausgeber | Schnur | Min: 1 Max: 8192 |
Zulässige Werte pro X.509 |
VerlegerId | Schnur | Min: 13 Max: 13 |
Base32 codiert, Crockford-Variante, das heißt [a-hjkmnp-tv-z0-9] |
Was ist ein 'Package String'?
Eine Paketzeichenfolge ist eine Zeichenfolge, die die folgenden Zeichen zulässt:
- Zulässige Eingabezeichen (ASCII-Teilmenge)
- Großbuchstaben (U+0041 bis U+005A)
- Kleinbuchstaben (U+0061 bis U+007A)
- Zahlen (U+0030 bis U+0039)
- Punkt (U+002E)
- Strich (U+002D)
Die folgenden Werte dürfen nicht als Paketzeichenfolgen verwendet werden:
Zustand | Unzulässige Werte |
---|---|
Darf nicht gleich sein | ".", "..", "con", "prn", "aux", "nul", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9" |
Kann nicht beginnen mit | "con.", "prn.", "aux.", "nul.", "com1.", "com2.", "com3.", "com4.", "com5.", "com6.", "com7.", "com8.", "com9.", "lpt1.", "lpt2.", "lpt3.", "lpt4.", "lpt5.", "lpt6.", "lpt7.", "lpt8.", "lpt9.", "xn---" |
Kann nicht mit ... enden | "." |
Kann nicht enthalten sein | .xn-- |
Eine Paketzeichenfolge muss mit einer ordinalen Zeichenfolgenvergleichs-APIs (z. B. _wcsicmp) verglichen werden.
Die Felder name
und resourceid
der Paketidentität sind Paketzeichenfolgen.
PackageId-Objekt
Eine PackageId ist ein Objekt, das das 5-teilige Tupel als individuelle Felder enthält (Name
, Version
, Architecture
, ResourceId
, Publisher
).
Vollständiger Paketname
Ein Vollständiger Paketname ist eine undurchsichtige Zeichenfolge, die von allen 5 Teilen der Identität eines Pakets abgeleitet ist (Name, Version, Architektur, Ressourcen-ID, Herausgeber)
<Name>_<Version>_<Architecture>_<ResourceId>_<PublisherId>
Beispielsweise lautet ein vollständiger Paketname für die Windows Fotos-App "Microsoft.Windows.Photos_2020.20090.1002.0_x64__8wekyb3d8bbwe", wobei "Microsoft.Windows.Photos" der Name, "2020.20090.1002.0" die Versionsnummer, "x64" die Zielprozessorarchitektur ist, die Ressourcen-ID ist leer (kein Inhalt zwischen den letzten beiden Unterstrichen), und "8wekyb3d8bbwe" ist die Publisher-ID für Microsoft.
Der vollständige Paketname identifiziert eindeutig ein MSIX Paket oder Bündel. Es ist ein Fehler, zwei Pakete oder Bündel mit unterschiedlichen Inhalten, aber mit demselben vollständigen Paketnamen zu haben.
Hinweis
MSIX ist der neue Name für den vorherigen Begriff APPX. Weitere Informationen finden Sie unter Was ist MSIX?
Paketfamilienname
Ein Paketfamilienname ist eine undurchsichtige Zeichenfolge, die aus nur zwei Teilen einer Paketidentität abgeleitet ist – Name und Herausgeber:
<Name>_<PublisherId>
Beispielsweise lautet der Paketfamilienname der Windows Fotos-App "Microsoft.Windows.Photos_8wekyb3d8bbwe", wobei "Microsoft.Windows.Photos" der Name und "8wekyb3d8bbwe" die Herausgeber-ID für Microsoft ist.
Der Paketfamilienname wird häufig als "vollständiger Paketname ohne Version" bezeichnet.
Hinweis
Dies ist nicht ganz zutreffend, da dem Paketfamilienname auch die Architektur und die Ressourcen-ID fehlen.
Hinweis
Daten und Sicherheit sind in der Regel auf eine Paketfamilie beschränkt. Es wäre beispielsweise keine gute Benutzererfahrung, wenn Sie die Notepad-App, die aus einem Notepad-Version-1.0.0.0-Paket installiert wurde, so konfigurieren, dass der Zeilenumbruch aktiviert wird. Dann wurde Notepad auf 1.0.0.1 aktualisiert und Ihre Konfigurationsdaten wurden nicht auf die neuere Version des Pakets übertragen.
Herausgeber-ID
Ein Paketfamilienname ist eine Zeichenfolge mit dem Format:
<name>_<publisherid>
Die Publisher-ID hat einige sehr spezifische Eigenschaften:
- Abgeleitet von Publisher
- MinLength = MaxLength = 13 Zeichen [feste Größe]
- Zulässige Zeichen (als regex) = a-hj-km-np-tv-z0-9
- Base-32, Crockford Variant, d. h. alphanumerisch (A-Z0-9) außer I (Auge), L (ell), O (oh) oder U (Sie)
- Ordinalfall-insensitiv für Vergleiche --- ABCDEFABCDEFG == abcdefabcdefg
Sie werden also nie % sehen: \ / " ? oder andere Zeichen in einer Publisher-Id.
Schauen Sie für weitere Details unter PackageFamilyNameFromId und PackageNameAndPublisherIdFromFamilyName.
Publisher-ID wird häufig als PublisherId bezeichnet.
Warum ist Publisher-ID vorhanden?
Publisher-ID ist vorhanden, da Publisher dem X.509-Namen/Signierer Ihres Zertifikats entsprechen muss, also:
- Es kann sehr groß sein (Länge <= 8192 Zeichen)
- Sie kann Zeichen enthalten, die unpraktisch oder beschränkt sind (umgekehrter Schrägstrich usw.)
Diese Probleme können es schwierig oder unmöglich machen, einige X.509-Zeichenfolgen im Dateisystem, in der Registrierung, in URLs und anderen Kontexten zu verwenden.
Wie erstelle ich eine PublisherId?
Verwenden Sie PackageNameAndPublisherIdFromFamilyName, um die PublisherId
aus einem PackageFamilyName
zu extrahieren.
Verwenden Sie PackageIdFromFullName, um die PublisherId
aus einem PackageFullName
zu extrahieren.
Es ist selten erforderlich, eine PublisherId
aus Publisher
zu erstellen, aber es ist mit den verfügbaren APIs möglich.
#include <appmodel.h>
HRESULT PublisherIdFromPublisher(
_In_ PCWSTR publisher,
_Out_writes_(PACKAGE_PUBLISHERID_MAX_LENGTH + 1) PWSTR publisherId)
{
PCWSTR name{ L"xyz" };
const size_t nameLength{ ARRAYSIZE(L"xyz") - 1 };
const size_t offsetToPublisherId{ name + 1 }; // xyz_...publisherid...
PACKAGE_ID id{};
id.name = name;
id.publisher = publisher;
WCHAR familyName[PACKAGE_PUBLISHERID_MAX_LENGTH + 1]{};
UINT32 n{ ARRAYSIZE(familyName) };
RETURN_IF_WIN32_ERROR(PackageFamilyNameFromId(&id, &n, familyName);
RETURN_IF_FAILED(StringCchCopyW(publisherId, PACKAGE_PUBLISHERID_MAX_LENGTH + 1, familyName + offsetToPublisherId));
return S_OK;
}
Es folgt eine klassische Windows C-Implementierung desselben Vorgangs:
#include <appmodel.h>
HRESULT PublisherIdFromPublisher(
_In_ PCWSTR publisher,
_Out_writes_(PACKAGE_PUBLISHERID_MAX_LENGTH + 1) PWSTR publisherId)
{
const WCHAR c_name[]{ L"xyz" };
const UINT32 c_nameLength{ ARRAYSIZE(c_nameForPublisherToPublisherId) - 1 };
PACKAGE_ID id{};
id.name = c_name;
id.publisher = publisher;
WCHAR familyName[PACKAGE_PUBLISHERID_MAX_LENGTH + 1]{};
UINT32 n{ ARRAYSIZE(familyName) };
RETURN_IF_WIN32_ERROR(PackageFamilyNameFromId(&id, &n, familyName));
RETURN_IF_FAILED(StringCchCopyW(publisherId, PACKAGE_PUBLISHERID_MAX_LENGTH + 1, familyName + c_nameLength + 1);
return S_OK;
}
Dadurch wird die PublisherId erstellt, indem eine Paket-ID in einen Paketfamiliennamen mit dem resultierenden Format xyz_<publisherid>
konvertiert wird. Dieses Rezept ist stabil und zuverlässig.
Dazu müssen Sie nur mit "appmodel.h" aus dem SDK kompilieren und eine Verknüpfung mit kernel32.lib (oder kernelbase.lib, onecore.lib oder api-ms-win-appmodel-runtime-l1.lib bei Verwendung von APIsets) herstellen.
Grundlegendes zur Prozessorarchitektur in der Paketidentität
Ein häufiges Missverständnis bedeutet, dass Architecture=x64
das Paket nur x64-Code enthalten kann. Das stimmt nicht. Dies bedeutet, dass das Paket auf Systemen funktioniert, die x64-Code unterstützen und von x64-Apps verwendet werden können. Sie können ein Paket erstellen, das nur PDF-Dateien enthält, aber deklarieren <Identity Architecture=x64...>
, da es nur für die Installation auf x64-kompatiblen Systemen vorgesehen ist (z. B. x64-Pakete können nur auf x64- und (ab Windows 11) Arm64-Systemen installiert werden, da x86, Arm und Windows 10 Arm64-Systeme x64 nicht unterstützen).
Noch missverstandener bedeutet Architecture=neutral
, dass das Paket keinen ausführbaren Code enthält, nicht bedeutet, dass das Paket keinen ausführbaren Code enthält. Dies bedeutet, dass das Paket für alle Architekturen funktioniert. Sie können beispielsweise ein Paket erstellen, das eine AES-Verschlüsselungs-API enthält, die in JavaScript, Python, C# usw. geschrieben wurde, aber die Leistung ist auf Arm64-Systemen nicht akzeptabel. Daher fügen Sie eine optimierte Arm64-Binärdatei hinzu und implementieren die API, um sie zu verarbeiten:
void Encrypt(...)
{
HANDLE h{};
if (GetCpu() == arm64)
{
h = LoadLibrary(GetCurrentPackagePath() + "\bin\encrypt-arm64.dll")
p = GetProcAddress(h, "Encrypt")
return (*p)(...)
}
else
{
// ...call other implementation...
}
}
Oder Sie können ein neutrales Paket mit mehreren Varianten erstellen:
\
bin\
encrypt-x86.dll
encrypt-x64.dll
encrypt-arm.dll
encrypt-arm64.dll
Entwickler können dann LoadLibrary("bin\encrypt-" + cpu + ".dll")
verwenden, um die entsprechende Binärdatei für ihren Prozess während der Laufzeit zu erhalten.
In der Regel haben neutrale Pakete keinen Inhalt pro Architektur, aber das können sie haben. Es gibt Grenzen, was man tun kann (z. B. könnten Sie ein Notepad-Paket erstellen, das mit notepad.exe für x86 + x64 + arm + arm64 kompiliert ist, aber appxmanifest.xml kann nur <Application Executable=...>
deklarieren, das auf eine davon zeigt). Da es Bündel gibt, mit denen Sie nur die erforderlichen Komponenten installieren können, ist das sehr ungewöhnlich. Es ist nicht illegal, bloß fortgeschritten und exotisch.
Außerdem bedeutet Architecture=x86
(oder x64|arm|arm64) nicht, dass das Paket nur ausführbaren Code für die angegebene Architektur enthält. Es ist nur der überwältigend häufige Fall.
Hinweis
Bei der Diskussion von "Code" oder "ausführbarem Code" in diesem Kontext verweisen wir auf portable ausführbare Dateien (PE).
Ist die Paketidentität groß-/kleinschreibungssensitiv?
Die Groß- und Kleinschreibung wird meist nicht beachtet, aber bei Publisher
schon.
Die verbleibenden Felder (Name
, ResourceId
, PublisherId
, PackageFullName
und PackageFamilyName
) sind nicht vorhanden. Bei diesen Feldern wird die Groß-/Kleinschreibung beibehalten, jedoch beim Vergleichen nicht beachtet.
Siehe auch
Windows developer