Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La identidad del paquete es un identificador único en el espacio y el tiempo. Al igual que tu ADN te identifica de forma única, la identidad del paquete identifica de forma única a un paquete.
Un paquete tiene un conjunto asociado de bits (archivos, etc.). No hay dos paquetes con la misma identidad y los cambios en los bits asociados a un paquete requieren una identidad diferente.
¿Qué es la identidad del paquete?
Una identidad de paquete es una construcción lógica que identifica de forma única un paquete. La identidad tiene cinco partes:
- Nombre: Este es un nombre elegido por el desarrollador de aplicaciones. Microsoft Store garantiza la exclusividad de todos los nombres de aplicaciones para todos los desarrolladores dentro de la Tienda, pero no se asegura que los nombres sean únicos dentro del ecosistema general.
- Versión: Número de versión del paquete. El desarrollador de aplicaciones puede elegir números de versión arbitrarios, pero debe asegurarse de que los números de versión aumenten con las actualizaciones.
- Arquitectura: La arquitectura del procesador objetivo del paquete. La misma aplicación se puede compilar para diferentes arquitecturas de procesador, con cada compilación residiendo en su propio paquete.
-
ResourceId: Cadena elegida por el desarrollador de aplicaciones para identificar de forma única los paquetes de recursos, por ejemplo diferentes idiomas o escalas de presentación diferentes. Los paquetes de recursos suelen ser independientes de la arquitectura. Para las agrupaciones, el ResourceId es siempre
~. - Publisher: El nombre del sujeto del desarrollador de la aplicación, tal como lo identifica su certificado de firma. Esto es teóricamente único para cada desarrollador de aplicaciones, ya que las entidades de certificación de reputación usan nombres e identidades únicos del mundo real para rellenar el campo de nombre del firmante del certificado.
Esta construcción a veces se conoce como la tupla de 5 partes .
Nota:
Límites de campos de identidad del paquete
| Campo | Tipo de dato | Límites | Comentarios |
|---|---|---|---|
| Nombre | Cadena de paquete | Min: 3 Máximo: 50 |
Valores permitidos por Validate API (consulte Package String) |
| Versión | DotQuad | Min: 0.0.0.0 Max: 65535.65535.65535.65535 |
El formulario de cadena usa la notación de puntos base-10, "Major.Minor.Build.Revision" |
| Arquitectura | Enumeración | Min: N/A Máximo: N/A |
Los valores permitidos son "neutral", "x86", "x64", "arm", "arm64", "x86a64" |
| ResourceId | Cadena de paquete | Min: 0 Máximo: 30 |
Valores permitidos por Validate API (consulte Package String) |
| Publicador | Cuerda | Min: 1 Máximo: 8192 |
Valores permitidos por X.509 |
| ID de Publicador | Cuerda | Min: 13 Máximo: 13 |
Codificada en Base32, variante Crockford, es decir, [a-hjkmnp-tv-z0-9] |
¿Qué es una cadena de paquete?
Una cadena de paquete es una cadena que permite los siguientes caracteres:
- Caracteres de entrada permitidos (subconjunto ASCII)
- Letras mayúsculas (U+0041 a U+005A)
- Letras minúsculas (U+0061 a U+007A)
- Números (U+0030 a U+0039)
- Punto (U+002E)
- Guión (U+002D)
Se prohíbe usar los siguientes valores como cadenas de paquete:
| Condición | Valores prohibidos |
|---|---|
| No se puede igualar | ".", "..", "con", "prn", "aux", "nul", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9" |
| No se puede comenzar con | "con.", "prn.", "aux.", "nul.", "com1.", "com2.", "com3.", "com4.", "com5.", "com6.", "com7.", "com8.", "com9.", "lpt1.", "lpt2.", "lpt3.", "lpt4.", "lpt5.", "lpt6.", "lpt7.", "lpt8.", "lpt9.", "xn--" |
| No se puede terminar con | "." |
| No puede contener | ".xn---" |
Una cadena de paquete debe compararse mediante una API de comparación de cadenas sin distinción entre mayúsculas y minúsculas (por ejemplo, _wcsicmp).
Los campos name y resourceid de la Identidad del Paquete son cadenas de paquete.
objeto PackageId
Un PackageId es un objeto que contiene la tupla de 5 partes como campos individuales (Name, Version, Architecture, ResourceId, Publisher).
Nombre completo del paquete
Un nombre completo del paquete es una cadena opaca derivada de la identidad de un paquete (nombre, versión, arquitectura, resourceid, publicador)
<Name>_<Version>_<Architecture>_<ResourceId>_<PublisherId>
Por ejemplo, un nombre completo de paquete para la aplicación Fotos de Windows es "Microsoft.Windows.Photos_2020.20090.1002.0_x64__8wekyb3d8bbwe", donde "Microsoft.Windows.Photos" es el nombre, "2020.20090.1002.0" es el número de versión, "x64" es la arquitectura del procesador de destino, el identificador de recurso está vacío (sin contenido entre los dos últimos caracteres de subrayado) y "8wekyb3d8bbwe" es el identificador de publicador de Microsoft.
El Nombre Completo del Paquete identifica de manera única un paquete o conjunto MSIX . Es un error tener dos paquetes o agrupaciones con contenido diferente, pero con el mismo nombre completo del paquete.
Nota:
MSIX es el nuevo nombre para el término anterior APPX. Para obtener más información, consulte ¿Qué es MSIX?
Nombre de familia del paquete
Un nombre de familia de paquete de
<Name>_<PublisherId>
Por ejemplo, el nombre de familia del paquete de la aplicación Fotos de Windows es "Microsoft.Windows.Photos_8wekyb3d8bbwe", donde "Microsoft.Windows.Photos" es el nombre y "8wekyb3d8bbwe" es el identificador de publicador de Microsoft.
El nombre de familia del paquete a menudo se conoce como un "nombre del paquete completo sin versión".
Nota:
Esto no es estrictamente cierto, ya que el nombre de familia del paquete también carece de arquitectura e identificador de recurso.
Nota:
Los datos y la seguridad suelen tener como ámbito una familia de paquetes. Por ejemplo, sería una mala experiencia si configuraste la aplicación bloc de notas instalada desde un paquete del Bloc de notas 1.0.0.0 para habilitar Wordwrap. A continuación, el Bloc de notas se actualizó posteriormente a la versión 1.0.0.1 y los datos de configuración no se llevaron a la versión más reciente del paquete.
Id. del publicador
Un nombre de familia de paquete es una cadena con el formato :
<name>_<publisherid>
donde id. de publicador tiene algunas propiedades muy específicas:
- Derivado de Publisher
- MinLength = MaxLength = 13 caracteres [tamaño fijo]
- Caracteres permitidos (como regex) = a-hj-km-np-tv-z0-9
- Base-32, Crockford Variant, es decir, alfanumérico (A-Z0-9) excepto no I (ojo), L (ell), O (oh) u U (usted)
- Ordinal no distingue mayúsculas de minúsculas para comparaciones --- ABCDEFABCDEFG == abcdefabcdefg
Por lo tanto, nunca verá % : \ / " ? u otros caracteres de un identificador de publicador.
Consulte PackageFamilyNameFromId y PackageNameAndPublisherIdFromFamilyName para obtener más detalles.
El identificador del publicador se conoce a menudo como PublisherId.
¿Por qué existe el identificador del publicador?
Publisher Id existe porque Publisher Id debe coincidir con el nombre o firmante X.509 de tu certificado, por lo que:
- Puede ser muy grande (longitud <= 8192 caracteres)
- Puede incluir caracteres que son difíciles de usar o tienen restricciones (barra invertida, etc.)
Estos problemas pueden hacer que algunas cadenas X.509 sean complicadas o imposibles de usar en el sistema de archivos, el registro, las direcciones URL y otros contextos.
¿Cómo se crea un PublisherId?
Usa PackageNameAndPublisherIdFromFamilyName para extraer el PublisherId de un PackageFamilyName.
Usa PackageIdFromFullName para extraer el PublisherId de un PackageFullName.
Es poco frecuente que necesite crear a PublisherId partir de Publisher, pero se puede hacer con el uso de las API disponibles:
#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;
}
A continuación se muestra una implementación clásica de Windows C de la misma operación:
#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;
}
Esto crea el PublisherId convirtiendo un identificador de paquete en un nombre de familia de paquetes con el formato xyz_<publisherid>resultante. Esta receta es estable y confiable.
Esto solo requiere compilar con appmodel.h desde el SDK y vincularlo con kernel32.lib (o kernelbase.lib, onecore.lib o api-ms-win-appmodel-runtime-l1.lib si usa APIets).
Comprensión de la arquitectura del procesador en la identidad del paquete
Un malentendido común es que significa que Architecture=x64 el paquete solo puede contener código x64. Esto no es cierto. Significa que el paquete funciona en sistemas que admiten código x64 y que las aplicaciones x64 pueden usar. Puedes crear un paquete que contenga solo archivos PDF, pero declararlo con <Identity Architecture=x64...> porque solo está diseñado para instalarse en sistemas compatibles con x64 (por ejemplo, los paquetes x64 solo se pueden instalar en sistemas x64 y (a partir de Windows 11) Arm64, ya que los sistemas Arm86, Arm y Windows 10 Arm64 no admiten x64).
Aún más mal entendido, Architecture=neutral no significa que el paquete no contiene código ejecutable. Significa que el paquete funciona en todas las arquitecturas. Por ejemplo, podría crear un paquete que contenga una API de cifrado AES escrita en JavaScript, Python, C#, etc., pero el rendimiento no es aceptable en los sistemas Arm64. Por lo tanto, incluye un binario arm64 optimizado e implementa la API para controlarlo:
void Encrypt(...)
{
HANDLE h{};
if (GetCpu() == arm64)
{
h = LoadLibrary(GetCurrentPackagePath() + "\bin\encrypt-arm64.dll")
p = GetProcAddress(h, "Encrypt")
return (*p)(...)
}
else
{
// ...call other implementation...
}
}
O bien, puede crear un paquete neutro con varias variantes:
\
bin\
encrypt-x86.dll
encrypt-x64.dll
encrypt-arm.dll
encrypt-arm64.dll
A continuación, los desarrolladores pueden ejecutar el comando LoadLibrary("bin\encrypt-" + cpu + ".dll") para obtener el binario adecuado para su proceso en tiempo de ejecución.
Normalmente, los paquetes neutros no tienen contenido por arquitectura, pero pueden. Hay un límite en lo que puede hacer (por ejemplo, puede hacer un paquete del Bloc de notas que contenga notepad.exe compilado para x86 + x64 + arm + arm64, pero appxmanifest.xml solo puede declarar <Application Executable=...> que apunte a uno de ellos). Dado que hay agrupaciones que permiten instalar solo los bits necesarios, esto es algo muy poco común. No es ilegal, sólo avanzado y exótico.
Además, Architecture=x86 (o x64|arm|arm64) no significa que el paquete solo contenga código ejecutable para la arquitectura especificada. Es sólo el caso abrumadormente común.
Nota:
Al analizar "código" o "código ejecutable" en este contexto, nos referimos a archivos ejecutables portátiles (PE).
¿La identidad del paquete distingue entre mayúsculas y minúsculas?
En general, no, pero Publisher distingue mayúsculas de minúsculas.
Los campos restantes (Name, ResourceId, PublisherId, PackageFullName y PackageFamilyName) no lo son. Estos campos conservarán mayúsculas y minúsculas, pero comparan de forma insensible a las mayúsculas.
Consulte también
En el caso de variables o elementos de código que no deben traducirse, se recomienda dejar el texto original o utilizar una nomenclatura comúnmente aceptada en el contexto técnico en español.