HOWTO: Find the Path and Version of an Office Application from Visual C++
ID: Q247985
|
The information in this article applies to:
-
Microsoft Visual C++, 32-bit Professional Edition, versions 5.0, 6.0
-
Microsoft Office versions 2000, 97 for Windows
SUMMARY
This article explains how you can examine the registry at run time to determine the installation path and version of an Office application.
MORE INFORMATION
Each Office application is associated with a version independent ProgID and a CLSID. You can examine the registry for keys containing a server's CLSID and ProgID to determine both the installation path and version of the server application.
Steps to Create Sample
- Create an MFC Appwizard EXE named OfficePath. In step 1 of AppWizard, select Dialog Based and click Finish.
- Click the Resources tab and open the IDD_OFFICEPATH_DIALOG dialog box.
- Remove the OK and Cancel Buttons on the dialog box.
- Add an EditBox to the dialog box and name it IDC_PROGID.
- Add two CommandButtons to the dialog box. Name the CommandButtons IDPATH and IDVERSION and set the captions to GetPath and GetVersion respectively.
- Start ClassWizard.
- Add a function handler to the BN_CLICKED message of each CommandButton.
- Create a member variable for the EditBox IDC_PROGID. Name the member variable m_ProgID and specify Control for the category and CEdit for the variable type.
- Close the ClassWizard.
- In the OfficePathDlg.h file, add the following public member functions to the COfficePathDlg class:
static BOOL GetPath(LPOLESTR szApp, LPSTR szPath, ULONG cSize);
static BOOL GetVersion(LPCTSTR szApp, LPSTR szVersion, ULONG cSize);
- Add the following function definitions to OfficePathDlg.cpp:
void COfficePathDlg::OnPath()
{
LPOLESTR szwApp;
char szLocation[255], szApp[50];
// Get ProgID from EditBox
m_ProgID.GetWindowText(szApp, 50);
if (strcmp(szApp,"") == 0)
{
MessageBox("Type ProgID in EditBox", "Error");
return;
}
// Find number ofcharacters to be allocated
int len = strlen(szApp) + 1;
// Use OLE Allocator to allocate memory
szwApp = (LPOLESTR) CoTaskMemAlloc(len*2);
if (szwApp == NULL)
{
MessageBox("Out of Memory", "Error");
return;
}
// AnsiToUnicode conversion
if (0 == MultiByteToWideChar(CP_ACP, 0, szApp, len,
szwApp, len))
{
// Free Memory allocated to szwApp if conversion failed
CoTaskMemFree(szwApp);
szwApp = NULL;
MessageBox("Error in Conversion", "Error");
return;
}
// Get Path to Application and display it
if (!GetPath(szwApp, szLocation, 255))
MessageBox("Error Getting Path", "Error");
else
MessageBox(szLocation, "Path");
}
void COfficePathDlg::OnVersion()
{
CHAR szVersion[255], szApp[50];
// Get Version of Application
m_ProgID.GetWindowText(szApp, 50);
if (strcmp(szApp,"") == 0)
{
MessageBox("Type ProgID in EditBox", "Error");
return;
}
// Get Version and display it
if (!GetVersion(szApp, szVersion, 255))
MessageBox("Error Getting Version", "Error");
else
MessageBox(szVersion, "Version");
}
BOOL COfficePathDlg::GetPath(LPOLESTR szApp, LPSTR szPath, ULONG cSize)
{
CLSID clsid;
LPOLESTR pwszClsid;
CHAR szKey[128];
CHAR szCLSID[60];
HKEY hKey;
// szPath must be at least 255 char in size
if (cSize < 255)
return FALSE;
// Get the CLSID using ProgID
HRESULT hr = CLSIDFromProgID(szApp, &clsid);
if (FAILED(hr))
{
AfxMessageBox("Could not get CLSID from ProgID, Make sure ProgID is correct", MB_OK, 0);
return FALSE;
}
// Convert CLSID to String
hr = StringFromCLSID(clsid, &pwszClsid);
if (FAILED(hr))
{
AfxMessageBox("Could not convert CLSID to String", MB_OK, 0);
return FALSE;
}
// Convert result to ANSI
WideCharToMultiByte(CP_ACP, 0, pwszClsid, -1, szCLSID, 60, NULL, NULL);
// Free memory used by StringFromCLSID
CoTaskMemFree(pwszClsid);
// Format Registry Key string
wsprintf(szKey, "CLSID\\%s\\LocalServer32", szCLSID);
// Open key to find path of application
LONG lRet = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKey, 0, KEY_ALL_ACCESS, &hKey);
if (lRet != ERROR_SUCCESS)
{
// If LocalServer32 does not work, try with LocalServer
wsprintf(szKey, "CLSID\\%s\\LocalServer", szCLSID);
lRet = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKey, 0, KEY_ALL_ACCESS, &hKey);
if (lRet != ERROR_SUCCESS)
{
AfxMessageBox("No LocalServer Key found!!", MB_OK, 0);
return FALSE;
}
}
// Query value of key to get Path and close the key
lRet = RegQueryValueEx(hKey, NULL, NULL, NULL, (BYTE*)szPath, &cSize);
RegCloseKey(hKey);
if (lRet != ERROR_SUCCESS)
{
AfxMessageBox("Error trying to query for path", MB_OK, 0);
return FALSE;
}
// Strip off the '/Automation' switch from the path
char *x = strrchr(szPath, '/');
if(0!= x) // If no /Automation switch on the path
{
int result = x - szPath;
szPath[result] = '\0'; // If switch there, strip it
}
return TRUE;
}
BOOL COfficePathDlg::GetVersion(LPCTSTR szApp, LPSTR szVersion, ULONG cSize)
{
CHAR szKey[128], szValueName[128];
HKEY hKey, hKey1;
wsprintf(szKey, "%s", szApp);
LONG lRet = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKey, 0, KEY_ALL_ACCESS, &hKey);
if (lRet != ERROR_SUCCESS) {
// Word is registered, but no local server can be found!!!
AfxMessageBox("Could not get CLSID from ProgID, Make sure ProgID is correct", MB_OK, 0);
return FALSE;
}
wsprintf(szValueName, "%s", "CurVer");
lRet = RegOpenKeyEx(hKey, szValueName, 0, KEY_ALL_ACCESS, &hKey1);
if (lRet != ERROR_SUCCESS) {
// Excel is registered, but no local server can be found!!!
return FALSE;
}
// Get the Version information
lRet = RegQueryValueEx(hKey1, NULL, NULL, NULL, (BYTE*)szVersion, &cSize);
// Close the registry keys
RegCloseKey(hKey1);
RegCloseKey(hKey);
// Error while querying for value
if (lRet != ERROR_SUCCESS)
return FALSE;
// At this point szVersion contains the ProgID followed by a number.
// For example, Word 97 will return Word.Application.8 and Word 2000 will return Word.Application.9
// Store the version number
char *x = strrchr(szVersion, '.');
szVersion[0] = *(x + 1);
szVersion[1] = '\0';
if (strcmp(szVersion, "6") == 0)
strcpy(szVersion, "Version 95");
else if (strcmp(szVersion, "8") == 0)
strcpy(szVersion, "Version 97");
else if (strcmp(szVersion, "9") == 0)
strcpy(szVersion, "Version 2000");
else
strcpy(szVersion, "Version unknown");
return TRUE;
}
- Build the Project.
When you run the application, type the ProgID for an Office application in the edit box. Note: an example of a ProgID is Word.Application. Click the GetPath button to retrieve the path and click the GetVersion button to retrieve the registered version.
Additional Notes
If you have multiple versions of an Office application installed on your system, the version number corresponds to the application that is registered. In most cases, the registered version is the last version you ran.
If the server application is not installed, the calls to open its associated registry keys fail. You can use error handling in this situation to determine if the server application is installed.
REFERENCESQ240794 HOWTO: Determine the Path for an Office Application
Q234788 HOWTO: Find the Installation Path of an Office 2000 Application
© Microsoft Corporation 1999, All Rights Reserved. Contributions by Harsha Bennur, Microsoft Corporation
Additional query words:
directory
Keywords : kbRegistry kbVC kbGrpDSO kbDSupport
Version : WINDOWS:2000,97; winnt:5.0,6.0
Platform : WINDOWS winnt
Issue type : kbhowto
|