Solved

Get CLSID from ocx filename

Posted on 2000-05-18
20
2,380 Views
Last Modified: 2013-11-20
How can I get the CLSID of one control
when I just have the name/path of the ocx file?
0
Comment
Question by:jmartins71
  • 7
  • 5
  • 5
  • +2
20 Comments
 
LVL 11

Expert Comment

by:mikeblas
ID: 2823073
You can't.  The OCX file might implement more than one control.

..B ekiM
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 2823156
you can always search the registry - to see if it matches in there - not sensible to do in a program but you can use regedit
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 2823163
or if it has a typelibrary you could load that and parse it - I think there are tools available to do that - that could be a programmatical way
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
LVL 11

Expert Comment

by:mikeblas
ID: 2823972
> not sensible to do in a program but you can use regedit

Why not?

 > or if it has a typelibrary you could load that and parse it

Again, there may be more than one typelib in the control.

There's no identity between an OCX file and a given CLSID. You can enumerate a list of CLSIDs that are in a given OCX. But that's not the question that's been asked here.

I think you'll find that most efficient way to build that list really is to enumerate entries in the registry.

..B ekiM
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 2824703
> Why not?

I was thinking of time to complete - if it isn't a problem then go for it - but if it is only for 1 (one) .ocx then use regedit and the find option.
0
 
LVL 2

Expert Comment

by:wuxz
ID: 2824746
If you want to get to know this CLSID by your hands, you can use oleview to load this ocx file as a typelib file. But if you want to do this in your program, you should write a lot of codes to parse a typelib.

What do your actually want to do?
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 2824774
> What do your actually want to do?

that is a point - maybe if we knew what you wnated to do with it we could help :)
0
 

Author Comment

by:jmartins71
ID: 2824825
First of all thanks everybody!

In my application I need to switch between activex plugins.
Before I do this I need to get the CLSID from each ocx file the user wants to use. EACH OCX HAS ONLY ONE CONTROL.

Then I register this CLSID in my application registry entries.

The problem is of course how can I know the CLSID (or progID) just by knowing the ocx file that the user wants two use! Just one thing. I first register the control so the entries are in registry. but I am seing the filename like dos!!!

Mikeblas says I can not! That surprise me because if it is so how can Visual C++ wizard knows it when is creating one class for it (by doing add to project - activex)!!!!!

I have found on MSDN the following function:
"
GetClassFile
Supplies the CLSID associated with the given filename.

WINOLEAPI GetClassFile(
  LPCWSTR szFileName,
                  //Pointer to filename for which you are requesting
                  // a CLSID
  CLSID * pclsid  //Pointer to location for returning the CLSID
);

"

But I can not make it work! I am always getting the error code: MK_E_INVALIDEXTENSION

Maybe I am not using a good parameter for szFilename!?
What I am using is :
CString FileName; // with the filename and path of ocx file
BSTR temp = FileName.AllocSysString();

then use temp in szFileName.
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 2825031
> Mikeblas says I can not! That surprise me because if it is so how can Visual C++ wizard knows it when is creating one class for it (by doing add to project - activex)!!!!!

Visual Studio uses the typelibrary

>GetClassFile
>Supplies the CLSID associated with the given filename.

I thought that was for file extensions (read the remarks)

0
 
LVL 5

Expert Comment

by:vachooho
ID: 2825101
GetClassFile() used only for storage type files - like word's doc, excel's xls etc.

YOu can not use this function for exes.
BUt you always can search registry
HK_CLASSES_ROOT\CLSID\Inprocserver32 for file name of your OCX.
Be careful - path/filename may be converted to short.
0
 

Author Comment

by:jmartins71
ID: 2825258
Thanks,

I have found my file entry in win32 reg key!? Is this the same or was it generated by VStudio!?

Can I use this?

the path was HKEY_CLASSES_ROOT\typelib\(clsid)\1.0\0\win32


I have found as I say one file entry but has the ~chars (dos name files)

Two questions:
1) I do not know how to convert from my CString file to one dos filename.
2) How to begin one registry search?
Can you give me one api function for me to start.




0
 
LVL 5

Expert Comment

by:vachooho
ID: 2825367
all functions working with registry starts with Reg...
RegOpenKey
RegCreateKey
RegQueryValue
etc

or you can examine ATL's CRegKey class
it simplifies work with registry


http://www.codeguru.com/system/CRegKey.shtml
0
 

Author Comment

by:jmartins71
ID: 2825604
Ok,
I know CRegKey. But here is what I have found for my control:

HKEY_CLASSES_ROOT\CLSID\Inprocserver32
with "E:\TEMP\DUMMYP~1\DEBUG\DUMMYP~1.OCX"

Now I have "E:\TEMP\DUMMYPlatform\DEBUG\DUMMYplatform.OCX"

How to :
1)convert to string woth the dos limitations.
2) Query this key when I do not know the clsid to open it!?

Sorry but I am not understanding how to make registry queries on subkeys when I do not know the keys!?

0
 
LVL 11

Accepted Solution

by:
mikeblas earned 100 total points
ID: 2827784
> That surprise me because if it is so how can Visual C++ wizard knows it when
 > is creating one class for it (by doing add to project - activex)!!!!!

I'm sorry: I can't understand what you're saying.  You seem to be talking about the wizard that lets you add some wrapper classess from an ActiveX control.  That doesn't seem to be relevant to your problem, as using that feature involves selecting a control by it's registered object name, not by selecting a file name.  You're asking about selecting a file name.

 >  2) Query this key when I do not know the clsid to open it!?  

You can use the RegEnumKeyEx() API. I guess I'm becoming more and more lenient--I normally never write code for so few points.  But let me help you out. Here is a program you can build from the command line:

-- begin file findctl.cpp --

// compile with
//   cl findctl.cpp



#include <windows.h>
#include <stdio.h>

#define ELEMENTS(x)  (sizeof(x)/sizeof(x[0]))

#pragma comment(lib, "advapi32.lib")

const char* stristr(const char* pstrLeft, const char* pstrRight)
{
   int nRightLen = strlen(pstrRight);

   while (*pstrLeft)
   {
      if (toupper(*pstrLeft) == toupper(*pstrRight))
      {
         if (strnicmp(pstrLeft, pstrRight, nRightLen) == 0)
            return pstrLeft;
      }
      pstrLeft++;
   }

   return NULL;
}

int main(int argc, char* argv[])
{
   // check the arguments, print usage if no arg
   if (argc != 2)
   {
      printf("Usage:\n");
      printf("\tfindctl <matchname>\n");
      return 1;
   }

   LONG lRetVal;
   DWORD dwIndex = 0;

   // try to open the HKCR\CLSID hive for enumeration
   HKEY hKeyCLSID;
   lRetVal = RegOpenKeyEx(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &hKeyCLSID);
   if (lRetVal != ERROR_SUCCESS)
   {
      printf("Couldn't open HKCR\\CLSID!\n");
   }
   else
   {
      // enumerate each CLSID on this system
      do
      {
         char szBuffer[1024];
         DWORD dwBufLen = ELEMENTS(szBuffer);

         lRetVal = RegEnumKeyEx(hKeyCLSID, dwIndex, szBuffer, &dwBufLen, 0, NULL, NULL, NULL);

         if (lRetVal == ERROR_SUCCESS)
         {
            // if we've got one, try to open its InProcServer32 key
            char szFullName[1024];
            strcpy(szFullName, "CLSID\\");
            strcat(szFullName, szBuffer);
            strcat(szFullName, "\\InProcServer32");
//          printf("%s\n", szFullName);

            HKEY hKeyCurrent;
            LONG lOpened = RegOpenKeyEx(HKEY_CLASSES_ROOT, szFullName, 0, KEY_QUERY_VALUE, &hKeyCurrent);

            if (lOpened == ERROR_SUCCESS)
            {
               // if there's an InProcServer32 key, get its value
               char szFileName[1024];
               DWORD dwType;
               DWORD dwNameLen = ELEMENTS(szFileName);

               if (ERROR_SUCCESS == RegQueryValueEx(hKeyCurrent, NULL, NULL, &dwType,
                     (LPBYTE) szFileName, &dwNameLen))
               {
                  if (dwType == REG_SZ || dwType == REG_EXPAND_SZ)
                  {
                     // compare the server's file name with the name we were offered
                     // print 'em out, if there's a match
                     if (stristr(szFileName, argv[1]) != NULL)
                     {
                        printf("%s: %s\n", szBuffer, szFileName);
                     }
                  }
               }
               RegCloseKey(hKeyCurrent);
            }
         }

         dwIndex++;
      } while (lRetVal == ERROR_SUCCESS);

      RegCloseKey(hKeyCLSID);
   }

   return 0;
}


-- end file findctl.cpp --

This does what you want, but it also proves my point. On my machine, I have an OLE Control called Threed32.OCX.  It registers several different class IDs. My program finds them all:

{0BA686AA-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686AE-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686AF-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686B3-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686B4-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686B8-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686B9-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686BD-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686BE-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686C2-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686C3-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{0BA686C7-F7D3-101A-993E-0000C0EF6F5E}:      C:\WINNT\System32\Threed32.OCX
{2F155EE4-C332-11CD-B23C-0000C0058192}: C:\WINNT\System32\Threed32.OCX


Like I said, there's on one-to-one mapping between a server executable and OLE objects. A module can support more than one OLE control class--and, in efficient designs, often does!
You can't know "the" CLSID of an ole control given the file name.

..B ekiM

0
 

Author Comment

by:jmartins71
ID: 2832452
thank you mikeblas
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 2832467
If these are in-house objects and you still have the source you could always add a new exported function called something like GetOCXCLSID(CLSID * pCLSID) or something like that and make your task easier
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2854568

 > If these are in-house objects and you still have the
 > source you could always add a new exported function
 > called something like GetOCXCLSID(CLSID * pCLSID) or
 > something like that and make your task easier

I guess that might make the task a little easier, but it makes it very inefficient. Pawing through the whole HKCR\CLSID hive of the registry is going to be faster than loading a DLL, initializing it, and calling an entry point on it.

..B ekiM
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 2856307
> Pawing through the whole HKCR\CLSID hive of the registry is going to be faster than loading a DLL, initializing it, and calling an entry point on it

Really - I'd have thought it would be the other way round. I may do some tests if I ever need to do such a thing
0
 

Author Comment

by:jmartins71
ID: 2861542
I just want to make the following comment about How I have done it.

I have followed ShaunWilde comment because:

Since I have to register the control
I need to Load the DLL. The only thing I must do is to invoke another export function!
So, at least in my case is really better then parsing the registry.
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2863286
> Since I have to register the control

Oh. If you've got to load and install the control anyway, then it probably is better just to go poking for that extra export.

..B ekiM
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Perl Awk Need Help 3 128
Complete beginner needs help making a cron job 9 125
Hibernate methods 2 77
tripleUp challenge 7 86
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question