Interroger les informations du manifeste de package d’application (C++)
Découvrez comment obtenir des informations à partir du manifeste de package d’application pour une application Windows à l’aide de l’API d’empaquetage.
Créer un lecteur de manifeste de package
Pour créer un lecteur de manifeste de package, appelez IAppxFactory::CreatePackageReader pour créer un lecteur de package. Le premier paramètre est un flux d’entrée pour le package (fichier .appx). Le deuxième paramètre est un paramètre de sortie qui reçoit un pointeur vers un pointeur IAppxPackageReader . Ensuite, appelez IAppxPackageReader::GetManifest pour obtenir le lecteur de manifeste. Le paramètre est un paramètre de sortie qui reçoit un pointeur vers un pointeur IAppxManifestReader .
int wmain(
_In_ int argc,
_In_reads_(argc) wchar_t** argv)
{
HRESULT hr = S_OK;
if (argc != 2)
{
wprintf(L"Usage: DescribeAppx.exe inputFile\n");
wprintf(L" inputFile: Path to the app package to read\n");
return 2;
}
// Specify the appropriate COM threading model
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(hr))
{
IAppxPackageReader* packageReader = NULL;
IAppxManifestReader* manifestReader = NULL;
// Create a package reader using the file name given in command line
hr = GetPackageReader(argv[1], &packageReader);
// Get manifest reader for the package and read from the manifest
if (SUCCEEDED(hr))
{
hr = packageReader->GetManifest(&manifestReader);
}
if (SUCCEEDED(hr))
{
hr = ReadManifest(manifestReader);
}
}
}
//
// Creates an app package reader.
//
// Parameters:
// inputFileName
// Fully qualified name of the app package (.appx file) to be opened.
// reader
// On success, receives the created instance of IAppxPackageReader.
//
HRESULT GetPackageReader(
_In_ LPCWSTR inputFileName,
_Outptr_ IAppxPackageReader** reader)
{
HRESULT hr = S_OK;
IAppxFactory* appxFactory = NULL;
IStream* inputStream = NULL;
// Create a new factory
hr = CoCreateInstance(
__uuidof(AppxFactory),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IAppxFactory),
(LPVOID*)(&appxFactory));
// Create a stream over the input app package
if (SUCCEEDED(hr))
{
hr = SHCreateStreamOnFileEx(
inputFileName,
STGM_READ | STGM_SHARE_EXCLUSIVE,
0, // default file attributes
FALSE, // do not create new file
NULL, // no template
&inputStream);
}
// Create a new package reader using the factory. For
// simplicity, we don't verify the digital signature of the package.
if (SUCCEEDED(hr))
{
hr = appxFactory->CreatePackageReader(
inputStream,
reader);
}
// Clean up allocated resources
if (inputStream != NULL)
{
inputStream->Release();
inputStream = NULL;
}
if (appxFactory != NULL)
{
appxFactory->Release();
appxFactory = NULL;
}
return hr;
}
Lire les informations d’identité de package
L’identification de package est spécifiée à l’aide de l’élément Identity dans le manifeste. Utilisez IAppxManifestReader::GetPackageId pour obtenir un IAppxManifestPackageId pour lire les informations d’identité du package, comme illustré ici.
Ce code utilise IAppxManifestPackageId::GetPackageFullName pour obtenir le nom complet du package, IAppxManifestPackageId::GetName pour obtenir le nom du package et IAppxManifestPackageId::GetVersion pour obtenir la version du package.
//
// Reads a subset of the manifest Identity element.
//
//
HRESULT ReadManifestPackageId(
_In_ IAppxManifestReader* manifestReader)
{
HRESULT hr = S_OK;
IAppxManifestPackageId* packageId = NULL;
// Get elements and attributes from the manifest reader
hr = manifestReader->GetPackageId(&packageId);
if (SUCCEEDED(hr))
{
LPWSTR packageFullName = NULL;
LPWSTR packageName = NULL;
UINT64 packageVersion = 0;
hr = packageId->GetPackageFullName(&packageFullName);
if (SUCCEEDED(hr))
{
hr = packageId->GetName(&packageName);
}
if (SUCCEEDED(hr))
{
hr = packageId->GetVersion(&packageVersion);
}
if (SUCCEEDED(hr))
{
wprintf(L"Package full name: %s\n", packageFullName);
wprintf(L"Package name: %s\n", packageName);
wprintf(L"Package version: ");
// Convert version number from 64-bit integer to dot-quad form
for (int bitPosition = 0x30; bitPosition >= 0; bitPosition -= 0x10)
{
UINT64 versionWord = (packageVersion >> bitPosition) & 0xFFFF;
wprintf(L"%llu.", versionWord);
}
wprintf(L"\n");
}
// Free all string buffers returned from the manifest API
CoTaskMemFree(packageFullName);
CoTaskMemFree(packageName);
}
// Clean up allocated resources
if (packageId != NULL)
{
packageId->Release();
packageId = NULL;
}
return hr;
}
Lire les métadonnées qui décrivent le package aux utilisateurs
Les propriétés sont spécifiées à l’aide de l’élément Properties dans le manifeste. Utilisez IAppxManifestReader::GetProperties pour obtenir un IAppxManifestProperties pour lire ce nœud, comme illustré ici.
Ce code utilise IAppxManifestProperties::GetStringValue pour obtenir le nom d’affichage du package et la description du package.
//
// Reads a subset of the manifest Properties element.
//
//
HRESULT ReadManifestProperties(
_In_ IAppxManifestReader* manifestReader)
{
HRESULT hr = S_OK;
IAppxManifestProperties* properties = NULL;
// Get elements and attributes from the manifest reader
hr = manifestReader->GetProperties(&properties);
if (SUCCEEDED(hr))
{
LPWSTR displayName = NULL;
LPWSTR description = NULL;
hr = properties->GetStringValue(L"DisplayName", &displayName);
if (SUCCEEDED(hr))
{
hr = properties->GetStringValue(L"Description", &description);
}
if (SUCCEEDED(hr))
{
wprintf(L"Package display name: %s\n", displayName);
wprintf(L"Package description: %s\n", description);
}
// Free all string buffers returned from the manifest API
CoTaskMemFree(displayName);
CoTaskMemFree(description);
}
// Clean up allocated resources
if (properties != NULL)
{
properties->Release();
properties = NULL;
}
return hr;
}
Lire les métadonnées sur les applications incluses dans le package
Les applications sont spécifiées à l’aide de l’élément Applications dans le manifeste. Utilisez IAppxManifestReader::GetApplications pour obtenir un IAppxManifestApplicationsEnumerator pour lire ce nœud. Utilisez IAppxManifestApplicationsEnumerator::GetCurrent et IAppxManifestApplicationsEnumerator::MoveNext pour obtenir un IAppxManifestApplication pour chaque application du package.
Ce code utilise IAppxManifestApplication::GetStringValue pour obtenir le nom d’affichage de chaque application.
//
// Reads a subset of the manifest Applications element.
//
//
HRESULT ReadManifestApplications(
_In_ IAppxManifestReader* manifestReader)
{
HRESULT hr = S_OK;
BOOL hasCurrent = FALSE;
UINT32 applicationsCount = 0;
IAppxManifestApplicationsEnumerator* applications = NULL;
// Get elements and attributes from the manifest reader
hr = manifestReader->GetApplications(&applications);
if (SUCCEEDED(hr))
{
hr = applications->GetHasCurrent(&hasCurrent);
while (SUCCEEDED(hr) && hasCurrent)
{
IAppxManifestApplication* application = NULL;
LPWSTR applicationName = NULL;
hr = applications->GetCurrent(&application);
if (SUCCEEDED(hr))
{
application->GetStringValue(L"DisplayName", &applicationName);
}
if (SUCCEEDED(hr))
{
applicationsCount++;
wprintf(L"App #%u: %s\n", applicationsCount, applicationName);
}
if (SUCCEEDED(hr))
{
hr = applications->MoveNext(&hasCurrent);
}
if (application != NULL)
{
application->Release();
application = NULL;
}
CoTaskMemFree(applicationName);
}
wprintf(L"Count of apps in the package: %u\n", applicationsCount);
}
// Clean up allocated resources
if (applications != NULL)
{
applications->Release();
applications = NULL;
}
return hr;
}
Nettoyer le lecteur du manifeste de package
Avant de revenir à partir de la wmain
fonction, appelez la méthode Release pour propre le lecteur du manifeste du package et appelez la fonction CoUninitialize.
// Clean up allocated resources
if (manifestReader != NULL)
{
manifestReader->Release();
manifestReader = NULL;
}
if (packageReader != NULL)
{
packageReader->Release();
packageReader = NULL;
}
CoUninitialize();
Rubriques connexes
-
Exemples
-
Exemple de package d’application et de manifeste d’application de requête
-
Référence