Click to See Complete Forum and Search --> : Is it possible to find out what programs are installed in the start menu?
voidflux
May 13th, 2007, 01:23 PM
HEllo everyone, i've never used the WINAPI so I'm not sure if this will work or not...
I know C++ pretty well but I was wanting to do the following:
Find all the software installed on a system on the control pannel perhaps, and store all this information in a text file for later processing.
Kind of like an inventory control keeping track of what software is installed on a system.
I would then use PHP to read that text file and make it avaiable via a webpage.
Is this possible with the WINAPI or should I look else where?
TheCPUWizard
May 13th, 2007, 01:31 PM
Just look for the contents of:
<SystemDrive>:\Documents and Settings\All Users\Start Menu
and
<SystemDrive>:\Documents and Settings\<UserName>\Start Menu
Nothing special or API required....
voidflux
May 13th, 2007, 02:07 PM
Thanks for the responce.
Well 2 issues come to mind, this program will be run on more than 1 computer. So for every computer I won't know the <username>
Also wouldn't I have to read the icons text to see what program it is? With standard C++ I dont know how I would read an icons text or am I misunderstanding you when you say to
"Just look for the contents of:
<SystemDrive>:\Documents and Settings\All Users\Start Menu
and
<SystemDrive>:\Documents and Settings\<UserName>\Start Menu"
I found this function i wasn't sure if it was useful or not...
SHGetFolderPath Function () @ http://msdn2.microsoft.com/en-us/library/ms647764.aspx
and also this one:
http://msdn2.microsoft.com/en-us/library/ms649274.aspx
CSIDL_PROGRAMS
eero_p
May 14th, 2007, 02:07 AM
Just look for the contents of:
<SystemDrive>:\Documents and Settings\All Users\Start Menu
and
<SystemDrive>:\Documents and Settings\<UserName>\Start Menu
Nothing special or API required....
There is a flaw with that approach: Installed application is not detected if user has deleted its folder from the Start Menu.
TheCPUWizard
May 14th, 2007, 05:01 AM
True, that approach will only detech what is on the start menu.
Detecting everything that is installed, is virtually impossible, depending on what you mean by installed.
Consider a file that contains an executable program but the .exe has been renamied to .txt, therte is another program that will make a copy of this program ans "shell" to it. The propgram in question is runnable on the machine, but HOW are you going to detect it.....
voidflux
May 14th, 2007, 11:30 AM
Good point...
Well everything installed on the start menu is really what I need.
Everything installed on the system like you said would be quite hard.
I really don't understand how WinAPI works but I'm trying to get a process down on how I would code this first.
Once I find the directory to the start menu, I see all the programs listed, i'm assuming the user doesn't delete the start menu but from there is there a special way you can view the target perhaps of the icon...for instance,
If I go into the directory: C:\Documents and Settings\All Users\Start Menu\Programs
There is a list of all the programs, which I want.
Now there are 2 approaches I can either 2x click the folder and then check the properties of the .ink and it will show the target, If i could get the "target" path into a string then I could parse that string and find the name of the program, for instance for AIM it would be:
AIM6\aim6.exe" /d locale=en-US ee://aol/imApp
Or If I could simply go into the program files folder and read the icons file name that would give me the file name of the program exactly without going through all that other hassle.
voidflux
May 15th, 2007, 01:05 AM
OKay I think I figured out what I need....
Once I get the path which is located here: C:\Documents and settings\All Users\Programs once you go to this directory there are a bunch fo folders.
Is there a way to read the folder names and copy that into a text file?:wave:
I found this but i'm not sure how helpful it will be...
Heres a snippet in mfc for finding a file of form *.extension in directory = myDirectory
// Get a list of files
CFileFind finder;
BOOL finding = finder.FindFile (myDirectory + CString ("\\*.") + extension);
//iterate the results
while (finding)
{
finding = finder.FindNextFile();
//get file path
CString path = finder.GetFilePath());
//get file title
CString title = finder.GetFileTitle()
}
//dont forget to close
finder.Close ();
Also I thought these 2 functions might come in handy..
use _findfirst() and _findnext() to determine the file names
http://msdn2.microsoft.com/en-us/library/kda16keh(VS.71).aspx
This is for file names it seems....do you think there is a version for folder names?
eero_p
May 15th, 2007, 04:39 AM
One possibility to get a list of installed applications as seen in Control Panel's 'Add or remove programs', would be going throug registry.
Keys are located under path
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
And values 'DisplayName' are listed as uninstallable programs.
voidflux
May 15th, 2007, 05:54 PM
Thanks a ton eero_p I think you may have found exactly what I was needing!!
I've never worked with the registery but I am looking at the location you said:
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
and I see Display Name is exactly what I need to copy to a text file :D
When I click the Uninstall folder It shows the following:
Name: Default
Type: REG_SZ
Data: Value not Set
but all the folders under the Uninstall folder have more data such as:
Display Name: HP Photosmart
Type: REG_SZ
Data: HP Photosmart
I found this example that emerates the subkeys but i'm not sure if its what i'm looking for:
http://msdn2.microsoft.com/en-us/library/ms724256.aspx
// QueryKey - Enumerates the subkeys of key and its associated values.
// hKey - Key whose subkeys and values are to be enumerated.
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
void QueryKey(HKEY hKey)
{
TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
DWORD cbName; // size of name string
TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name
DWORD cchClassName = MAX_PATH; // size of class string
DWORD cSubKeys=0; // number of subkeys
DWORD cbMaxSubKey; // longest subkey size
DWORD cchMaxClass; // longest class string
DWORD cValues; // number of values for key
DWORD cchMaxValue; // longest value name
DWORD cbMaxValueData; // longest value data
DWORD cbSecurityDescriptor; // size of security descriptor
FILETIME ftLastWriteTime; // last write time
DWORD i, retCode;
TCHAR achValue[MAX_VALUE_NAME];
DWORD cchValue = MAX_VALUE_NAME;
// Get the class name and the value count.
retCode = RegQueryInfoKey(
hKey, // key handle
achClass, // buffer for class name
&cchClassName, // size of class string
NULL, // reserved
&cSubKeys, // number of subkeys
&cbMaxSubKey, // longest subkey size
&cchMaxClass, // longest class string
&cValues, // number of values for this key
&cchMaxValue, // longest value name
&cbMaxValueData, // longest value data
&cbSecurityDescriptor, // security descriptor
&ftLastWriteTime); // last write time
// Enumerate the subkeys, until RegEnumKeyEx fails.
if (cSubKeys)
{
printf( "\nNumber of subkeys: %d\n", cSubKeys);
for (i=0; i<cSubKeys; i++)
{
cbName = MAX_KEY_LENGTH;
retCode = RegEnumKeyEx(hKey, i,
achKey,
&cbName,
NULL,
NULL,
NULL,
&ftLastWriteTime);
if (retCode == ERROR_SUCCESS)
{
_tprintf(TEXT("(%d) %s\n"), i+1, achKey);
}
}
}
// Enumerate the key values.
if (cValues)
{
printf( "\nNumber of values: %d\n", cValues);
for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++)
{
cchValue = MAX_VALUE_NAME;
achValue[0] = '\0';
retCode = RegEnumValue(hKey, i,
achValue,
&cchValue,
NULL,
NULL,
NULL,
NULL);
if (retCode == ERROR_SUCCESS )
{
_tprintf(TEXT("(%d) %s\n"), i+1, achValue);
}
}
}
}
void _tmain(void)
{
HKEY hTestKey;
if( RegOpenKeyEx( HKEY_CURRENT_USER,
TEXT("SOFTWARE\\Microsoft"),
0,
KEY_READ,
&hTestKey) == ERROR_SUCCESS
)
{
QueryKey(hTestKey);
}
}
When they say "KEY"
Do they refer to that long string of characters and numbers as the folder name when you look in regedit?
like:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{00010409-78E1-11D2-B60F-006097C998E7}
and the { .... } is the key?
So really I should be looking for functions that can read all the "KEYS" under the directory:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
and access the KEYS DisplayName if a KEy has it, copy the DisplayName's value to a file;
if the key doesn't have a DisplayName value, skip that key?
Anyone know of any functions for accessing's a key's data if thats what its called?
I think this will direct me to the right directory but i'm not sure
how to go about reading the key's once I get to the directory because I don't know what the key value will be.
void _tmain(void)
{
HKEY hTestKey;
if( RegOpenKeyEx( HKEY_CURRENT_USER,
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"),
0,
KEY_READ,
&hTestKey) == ERROR_SUCCESS
)
{
QueryKey(hTestKey);
}
}
eero_p
May 16th, 2007, 02:58 AM
Yes, 'key's are the path-like strings, e.g. 'HKEY_LOCAL_MACHINE\SOFTWARE\'. You might want to see entries from both HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE.
In this case, it is enough to check if there is value called 'DisplayName' under the opened key with function RegQueryValueEx. See more at http://msdn2.microsoft.com/en-us/library/ms724911.aspx
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.