Click here to Skip to main content
15,891,184 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
Questionabout GetWindow function Pin
xrg_soft@163.com23-Feb-12 15:25
xrg_soft@163.com23-Feb-12 15:25 
AnswerRe: about GetWindow function Pin
Chris Losinger23-Feb-12 15:48
professionalChris Losinger23-Feb-12 15:48 
GeneralRe: about GetWindow function Pin
xrg_soft@163.com23-Feb-12 22:41
xrg_soft@163.com23-Feb-12 22:41 
AnswerRe: about GetWindow function Pin
ThatsAlok23-Feb-12 19:37
ThatsAlok23-Feb-12 19:37 
GeneralRe: about GetWindow function Pin
xrg_soft@163.com23-Feb-12 22:45
xrg_soft@163.com23-Feb-12 22:45 
GeneralRe: about GetWindow function Pin
ThatsAlok27-Feb-12 1:59
ThatsAlok27-Feb-12 1:59 
Questionc++, win32, optionalfeatures.exe, how it knows if a feature is installed, Data location Pin
jkirkerx23-Feb-12 10:28
professionaljkirkerx23-Feb-12 10:28 
AnswerRe: c++, win32, optionalfeatures.exe, how it knows if a feature is installed, Data location Pin
Randor 23-Feb-12 19:19
professional Randor 23-Feb-12 19:19 
Jim,

jkirkerx wrote:
I'm trying to discover a better way to determine if IIS is installed with
Windows Vista.


In one of my old installers it looks like I was checking for the existence of the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp however.. I wrote the installer back in 2006 so I do not know if that still works. You should investigate this.


jkirkerx wrote:
So I'm looking at Windows Feature, it know what features are installed, and I'm
trying to figure out the method it uses, or the location of the information.


Well I read the documentation for the MsiEnumComponents function[^] and came up with this:

C++
#include <Msi.h>
using namespace std;
#pragma comment(lib, "msi.lib")

VOID SampleEnumerateInstallsFromMSI()
{
	DWORD dwRet = 0;
	DWORD dwIndex = 0;
	TCHAR szProduct[MAX_GUID_CHARS + 1];

	while(ERROR_NO_MORE_ITEMS != dwRet)
	{
		dwRet = MsiEnumComponents(dwIndex, szProduct);
		if(ERROR_NO_MORE_ITEMS != dwRet)
		{
			TCHAR szProductName[MAX_PATH];
			DWORD dwCount = MAX_PATH;
			DWORD dwSuccess = MsiGetProductInfo(szProduct,INSTALLPROPERTY_PRODUCTNAME,szProductName,&dwCount);
			if(ERROR_SUCCESS == dwSuccess)
			{
				TRACE1("%s was installed from a MSI.\n",szProductName);
			}
			else if(ERROR_UNKNOWN_PRODUCT == dwSuccess)
			{
				//You can do a manual lookup in registry for non-MSI installations.
			}
		}
		++dwIndex;
	}
}


Unfortunately when I execute these MSI functions... it seems that it can only enumerate installations that used an MSI package. Here on my workstation it was missing litterally hundreds of software packages. So I decided that I would dig a little deeper and see if I could manage to read the registry and directly extract all of the installed software. Here is the result:

C++
// I decided to use TCHAR rather than CString or std::string/wstring but you could easily modify it to suit your needs.
#include <string>
#include <vector>

VOID SampleEnumerateInstallsFromRegistry()
{
	CRegKey reg;
	BOOL bWow64;
	HKEY hkeyLM = HKEY_LOCAL_MACHINE;
	TCHAR szBasekey[] = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData");

	IsWow64Process(GetCurrentProcess(),&bWow64);

	LONG lResult = reg.Open(hkeyLM,szBasekey,TRUE == bWow64 ? KEY_WOW64_64KEY | KEY_READ:KEY_READ);
	if(ERROR_SUCCESS == lResult)
	{
		TCHAR key[MAX_PATH];
		DWORD dwError =0;
		int iIndex = 0;
		DWORD dwLength = MAX_PATH;

		while(ERROR_SUCCESS == (dwError = reg.EnumKey(iIndex,key,&dwLength,0)))
		{
			CRegKey products_subkey;
			TCHAR szRegistryPath[MAX_PATH* 2];
			_tcscpy_s(szRegistryPath,MAX_PATH * 2,szBasekey);
			_tcscat_s(szRegistryPath,MAX_PATH * 2,_T("\\"));
			_tcscat_s(szRegistryPath,MAX_PATH * 2,key);
			_tcscat_s(szRegistryPath,MAX_PATH * 2, _T("\\Products"));

			lResult = products_subkey.Open(hkeyLM,szRegistryPath,TRUE == bWow64 ? KEY_WOW64_64KEY | KEY_READ:KEY_READ);
			if(ERROR_SUCCESS == lResult)
			{
				dwLength = MAX_PATH;
				int iIndexB = 0;
				while(ERROR_SUCCESS == (dwError = products_subkey.EnumKey(iIndexB,key,&dwLength,0)))
				{
					CRegKey install_key;
					TCHAR szFinalRegistryPath[MAX_PATH* 2];
					_tcscpy_s(szFinalRegistryPath,MAX_PATH * 2,szRegistryPath);
					_tcscat_s(szFinalRegistryPath,MAX_PATH * 2,_T("\\"));
					_tcscat_s(szFinalRegistryPath,MAX_PATH * 2,key);
					_tcscat_s(szFinalRegistryPath,MAX_PATH * 2,_T("\\InstallProperties"));

					lResult = install_key.Open(hkeyLM,szFinalRegistryPath,TRUE == bWow64 ? KEY_WOW64_64KEY | KEY_READ:KEY_READ);
					if(ERROR_SUCCESS == lResult)
					{
						TCHAR szDisplayName[MAX_PATH];
						dwLength = MAX_PATH;
						install_key.QueryStringValue(_T("DisplayName"),szDisplayName,&dwLength);
						TRACE1("%s was installed from a non-MSI installer.\n",szDisplayName);
					}

					dwLength = MAX_PATH;
					++iIndexB;
					install_key.Close();
				}
			}

			dwLength = MAX_PATH;
			++iIndex;
			products_subkey.Close();
		}
	}

	reg.Close();
}


Anyway it looks like it is enumerating just about everything I have installed on my workstation. Hopefully you will find it useful and if not maybe someone else will.

Best Wishes,
-David Delaune
GeneralRe: c++, win32, optionalfeatures.exe, how it knows if a feature is installed, Data location Pin
Peter_in_278023-Feb-12 19:39
professionalPeter_in_278023-Feb-12 19:39 
GeneralRe: c++, win32, optionalfeatures.exe, how it knows if a feature is installed, Data location Pin
jkirkerx23-Feb-12 21:20
professionaljkirkerx23-Feb-12 21:20 
QuestionCDockablePane Maximize button Pin
Member 773975323-Feb-12 7:58
Member 773975323-Feb-12 7:58 
QuestionRe: CDockablePane Maximize button Pin
Member 773975329-Feb-12 11:02
Member 773975329-Feb-12 11:02 
Questionplease send explaination Pin
Member 864805622-Feb-12 20:37
Member 864805622-Feb-12 20:37 
AnswerRe: please send explaination Pin
Chandrasekharan P22-Feb-12 20:49
Chandrasekharan P22-Feb-12 20:49 
AnswerRe: please send explaination Pin
CPallini22-Feb-12 22:39
mveCPallini22-Feb-12 22:39 
AnswerRe: please send explaination Pin
Luc Pattyn23-Feb-12 0:31
sitebuilderLuc Pattyn23-Feb-12 0:31 
GeneralRe: please send explaination Pin
CPallini23-Feb-12 3:12
mveCPallini23-Feb-12 3:12 
AnswerRe: please send explaination Pin
Luc Pattyn23-Feb-12 3:15
sitebuilderLuc Pattyn23-Feb-12 3:15 
GeneralRe: please send explaination Pin
CPallini23-Feb-12 10:16
mveCPallini23-Feb-12 10:16 
GeneralRe: please send explaination Pin
Luc Pattyn23-Feb-12 13:12
sitebuilderLuc Pattyn23-Feb-12 13:12 
GeneralRe: please send explaination Pin
CPallini23-Feb-12 21:53
mveCPallini23-Feb-12 21:53 
AnswerRe: please send explaination Pin
Chris Losinger23-Feb-12 1:27
professionalChris Losinger23-Feb-12 1:27 
AnswerRe: please send explaination Pin
JohnNawrocki23-Feb-12 2:08
JohnNawrocki23-Feb-12 2:08 
GeneralRe: please send explaination Pin
Richard MacCutchan23-Feb-12 2:36
mveRichard MacCutchan23-Feb-12 2:36 
AnswerRe: please send explaination Pin
Eytukan23-Feb-12 3:56
Eytukan23-Feb-12 3:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.