2022. 1. 20. 15:27

How to list installed programs using IShellAppManager

// appwiz.cpl is COM server related to (UnInstall or Change a program)
#include <shappmgr.h>
#include <iostream>
#import <appwiz.cpl>

// If this import gets into trobule, you could solve the problem by using #import directives
/*
#import <appwiz.cpl> rename("tag_inner_PROPVARIANT", "_tag_inner_PROPVARIANT") \
inject_statement("typedef struct _LARGE_INTEGER2 { LONGLONG QuadPart; } LARGE_INTEGER2;") \
inject_statement("typedef struct _ULARGE_INTEGER2 { ULONGLONG QuadPart;} ULARGE_INTEGER2;") \
rename("_LARGE_INTEGER", " _LARGE_INTEGER2") \
rename("_ULARGE_INTEGER", "_ULARGE_INTEGER2")
*/

int main()
{

	::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

	class __declspec(uuid("{352EC2B7-8B9A-11D1-B8AE-006008059382}")) AppWiz;
	static const CLSID CLSID_AppWiz = __uuidof(AppWiz);

	SHAPPMGRPLib::IShellAppManagerPtr spShellAppManaager;
	HRESULT hr = spShellAppManaager.CreateInstance(CLSID_AppWiz, NULL, CLSCTX_INPROC_SERVER);

	SHAPPMGRPLib::IEnumInstalledAppsPtr spEnumInstalledApps;
	hr = spShellAppManaager->EnumInstalledApps(&spEnumInstalledApps);

	SHAPPMGRPLib::IInstalledAppPtr spInstalledApp;
	SHAPPMGRPLib::IInstalledApp* pInstalledApp;
	
	while (S_OK == (hr = spEnumInstalledApps->Next(&pInstalledApp))) {

		spInstalledApp = pInstalledApp;


		SHAPPMGRPLib::_AppInfoData data = { 0 };
		data.cbSize = sizeof(SHAPPMGRPLib::_AppInfoData);
		data.dwMask = AIM_DISPLAYNAME | AIM_VERSION | AIM_PUBLISHER | AIM_INSTALLDATE;

		hr = spInstalledApp->GetAppInfo(&data);

		// You have to check the validation of the data before using it.

		std::wcout << "Name: " << data.pszDisplayName << " ver: " << data.pszVersion
			<< " publisher: " << data.pszPublisher << " installedOn: " << data.pszInstallDate << std::endl;

	}

	::CoUninitialize();

	return 0;
}