アプリ パッケージ マニフェスト情報のクエリ (C++)
パッケージ API を使用して Windows アプリのアプリ パッケージ マニフェストから情報を取得する方法について説明します。
パッケージ マニフェスト リーダーを作成する
パッケージ マニフェスト リーダーを作成するには、IAppxFactory::CreatePackageReader を呼び出してパッケージ リーダーを作成します。 最初のパラメーターは、パッケージ (.appx ファイル) の入力ストリームです。 2 番目のパラメーターは、IAppxPackageReader ポインターへのポインターを受け取る出力パラメーターです。 次に、IAppxPackageReader::GetManifest を呼び出してマニフェスト リーダーを取得します。 このパラメーターは、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;
}
パッケージ ID 情報を読み取る
パッケージ識別は、マニフェストの Identity 要素を使用して指定されます。 次に示すように、IAppxManifestReader::GetPackageId を使用して IAppxManifestPackageId を取得し、パッケージ ID 情報を読み取ります。
このコードでは、IAppxManifestPackageId::GetPackageFullName を使用してパッケージのフルネームを取得、IAppxManifestPackageId::GetName を使用してパッケージ名を取得し、IAppxManifestPackageId::GetVersion を使用してパッケージのバージョンを取得します。
//
// 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;
}
ユーザーにパッケージを説明するメタデータを読み込む
プロパティは、マニフェストの Properties 要素を使用して指定します。 次に示すように、IAppxManifestReader::GetProperties を使用して、このノードを読み取る IAppxManifestProperties を取得します。
このコードでは、IAppxManifestProperties::GetStringValue を使用して、パッケージの表示名とパッケージの説明を取得します。
//
// 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;
}
パッケージに含まれるアプリに関するメタデータを読み込む
アプリは、マニフェストの Applications 要素を使用して指定されます。 IAppxManifestReader::GetApplications を使用して、このノードを読み取る IAppxManifestApplicationsEnumerator を取得します。 IAppxManifestApplicationsEnumerator::GetCurrent と IAppxManifestApplicationsEnumerator::MoveNext を使用して、パッケージ内の各アプリの IAppxManifestApplication を取得します。
このコードでは、IAppxManifestApplication::GetStringValue を使用して、各アプリの表示名を取得します。
//
// 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;
}
パッケージ マニフェスト リーダーをクリーンアップする
wmain
関数から戻る前に、Release メソッドを呼び出してパッケージ マニフェスト リーダーをクリーンアップし、CoUninitialize 関数を呼び出します。
// Clean up allocated resources
if (manifestReader != NULL)
{
manifestReader->Release();
manifestReader = NULL;
}
if (packageReader != NULL)
{
packageReader->Release();
packageReader = NULL;
}
CoUninitialize();
関連トピック
-
サンプル
-
リファレンス