none
Getting the ProgID from type RRS feed

  • Question

  • Is there a way to get ProgID of a component registered in the system from its type? I am trying to achieve something like the following

    Type t = Type.GetTypeFromProgID("ProgId");

    string progid = //somehow get the progID from the above type. Actually,i'll get an object of Type Object (which is like a wrapper for a ComObject) and from that i have to get the ProgID..

    I tried the following

     RegistrationServices reg = new RegistrationServices();
                reg.GetProgIdForType(t);
     and it threw an exception

    Thanks

    Thursday, May 27, 2010 7:22 PM

Answers

  • Something like this might work:

    [DllImport("ole32.dll")]
    static extern int ProgIDFromCLSID([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgID);
      
    . . .
           
    object tmpComObj = Activator.CreateInstance(comType);
    IPersist persist = comObj as IPersist;
    if (persist != null)
    {
        Guid classId;
        persist.GetClassID(out classId);
        string progId;
        ProgIDFromCLSID(ref classId, out progId);
        Console.WriteLine("Progid = {0}, CLSID = {1}", progId, classId);
    }
    Marshal.ReleaseComObject(tmpComObj);


    http://blog.voidnish.com
    Thursday, May 27, 2010 8:05 PM
    Moderator
  • You shouldn't have to reference anything - the COM interop DLL you already reference should have it defined. If for some reason you don't have it, you can manually add an interface to your project as follows :

    using System;
    using System.Runtime.InteropServices;

    namespace Your-namespace-can-be-anything
    {
        [InterfaceType(1)]
        [Guid("0000010C-0000-0000-C000-000000000046")]
        public interface IPersist
        {
            void GetClassID(out Guid pClassID);
        }
    }


    http://blog.voidnish.com
    • Marked as answer by Zest4Quest Wednesday, June 2, 2010 2:32 PM
    Tuesday, June 1, 2010 2:44 PM
    Moderator

All replies

  • Something like this might work:

    [DllImport("ole32.dll")]
    static extern int ProgIDFromCLSID([In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)] out string lplpszProgID);
      
    . . .
           
    object tmpComObj = Activator.CreateInstance(comType);
    IPersist persist = comObj as IPersist;
    if (persist != null)
    {
        Guid classId;
        persist.GetClassID(out classId);
        string progId;
        ProgIDFromCLSID(ref classId, out progId);
        Console.WriteLine("Progid = {0}, CLSID = {1}", progId, classId);
    }
    Marshal.ReleaseComObject(tmpComObj);


    http://blog.voidnish.com
    Thursday, May 27, 2010 8:05 PM
    Moderator
  • Hi Nishant,

      Thanks for the reply..but i think i didnt make my requirement very clear..Hope you can help..What i need is from an object of type Object(which actually points toa Com Object) get the ProgID string..

     

    for eg: 

    Type t = Type.GetTypeFromProgID("progID");

    Object oj = Activator.CreateInstance(t);

     would give me a Com Object wrapped..how would i get the ProgID from this Object?

     

    Thursday, May 27, 2010 8:31 PM
  • Yes, that's what I assumed you were asking about. In my example, that's what comType represents, a type that you obtained with a call to Type.GetTypeFromProgID(...).
    http://blog.voidnish.com
    Friday, May 28, 2010 2:02 PM
    Moderator
  • Hi Nishant,

     One final question.I see in MSDN that IPersist is part of microsoft.visualstudio.ole.interop.dll.And i searched the system for that and could not find the file to be added as referrence to the project.I am using VS2008 and XP.Could you please let me know about this. I tried adding the referrence using the "Browse" tab of "Add referrence" and it wont let me...Please advice..

    Thanks

    Tuesday, June 1, 2010 2:19 PM
  • You shouldn't have to reference anything - the COM interop DLL you already reference should have it defined. If for some reason you don't have it, you can manually add an interface to your project as follows :

    using System;
    using System.Runtime.InteropServices;

    namespace Your-namespace-can-be-anything
    {
        [InterfaceType(1)]
        [Guid("0000010C-0000-0000-C000-000000000046")]
        public interface IPersist
        {
            void GetClassID(out Guid pClassID);
        }
    }


    http://blog.voidnish.com
    • Marked as answer by Zest4Quest Wednesday, June 2, 2010 2:32 PM
    Tuesday, June 1, 2010 2:44 PM
    Moderator
  • Hi Nishant,

      Thanks for the reply.Allow me to ask just one more question related to this.If from an object thats actually holding a referrence to a ComObject, is it possible for me to get the Memberinfo like the following?

     IMyInterface intrf = comObj as IMyInterface;

    MemberInfo[] minfo = intrf.GetType().GetMembers();

     

    When i did this where comObj is of Type Object (__ComObject) i get only the methods of MarshallByRefObject class.How can i get the Members of the other interfaces that it implements?

    TIA

    Wednesday, June 2, 2010 6:37 PM
  • When you do intrf.GetType() it returns the System.__ComObject type, but since you already know the interface you can simply do typeof(YourInterface). In your example above, that would be:

    MemberInfo[] arr = typeof(IMyInterface).GetMembers();


    http://blog.voidnish.com
    Thursday, June 3, 2010 2:06 AM
    Moderator
  • Hi Nishant. But if i had a situation where i had a System.__ComObject and i wanted to query the interfaces it implemented and then get their members, how can i achieve it?

    TIA

    Thursday, June 3, 2010 8:38 PM
  • I found C++ code to get the interfaces. Here is the C# translation:
    public static List<string> GetInterfaces(object o)
    {
      IntPtr iUnknown = Marshal.GetIUnknownForObject(o);
    
      List<string> list = new List<string>();
      RegistryKey interfaceKey;
      if (iUnknown != null && (interfaceKey = Registry.ClassesRoot.OpenSubKey("Interface")) != null)
      {
        foreach (string subKeyName in interfaceKey.GetSubKeyNames())
        {
          try
          {
            Guid clsID = new Guid(subKeyName);
            IntPtr spObject;
            if (Marshal.QueryInterface(iUnknown, ref clsID, out spObject) == 0)
            {
              RegistryKey subKey = interfaceKey.OpenSubKey(subKeyName);
              list.Add((string)subKey.GetValue(""));
              subKey.Close();
            }
          }
          catch { }
        }
        interfaceKey.Close();
      }
      return list;
    }
    Friday, June 4, 2010 1:28 AM