2010-04-14 3 views
2

Edit: On dirait que Jon Skeet avait des questions similaires: How does the C# compiler detect COM types?

Get CLSID par l'interface PIA type

Comment puis-je obtenir le CLSID pour une interface donnée dans un interop primaire Assemblée? Voici ce que je parle:

// The c# compiler does some interesting magic. 
// The following code ... 
var app = new Microsoft.Office.Interop.Outlook.Application(); 

// ... is compiled like so (disassembled with Reflector): 
var app =((Microsoft.Office.Interop.Outlook.Application) 
    Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("0006F03A-0000-0000-C000-000000000046")))); 


Microsoft.Office.Interop.Outlook.Application est une interface, et donc il ne peut pas être instanciée directement. Ce qui est intéressant ici, c'est que C# vous permet de traiter ces interfaces COM comme si elles étaient des classes que vous pouvez instancier avec le mot-clé new. Ce que je veux savoir, étant donné le System.Type pour une interface donnée, comment puis-je obtenir le CLSID?

Note: Je veux finalement être en mesure de créer une instance étant donné System.Type de l'interface - Je ne me soucie pas vraiment comment. Je suppose ici que la façon la plus simple de faire ceci serait d'obtenir CLSID avec le Type, comme le fait le compilateur C#.

Répondre

0

Essayez la propriété GUID.

+1

J'ai essayé cela, mais cela ne me donne pas le GUID correct, comme dans ce qui suit: 'typeof (Outlook.Application) .GUID! = Type.GetTypeFromCLSID (nouveau Guid (" 0006F03A-0000-0000-C000- 000000000046 ")). GUID'. – Charles

2

Voilà ma solution actuelle:

// Get the PIA assemby name, using the GUID of the typlib 
string asmName; 
string asmCodeBase; 
var conv = new System.Runtime.InteropServices.TypeLibConverter(); 
conv.GetPrimaryInteropAssembly(new Guid("00062FFF-0000-0000-C000-000000000046"), 9, 3, 0, out asmName, out asmCodeBase); 

// Load the PIA, and get the interface type 
var assembly = System.Reflection.Assembly.Load(asmName); 
var type = assembly.GetType("Microsoft.Office.Interop.Outlook.Application"); 

// Get the coclass 
var coClassAttr = (System.Runtime.InteropServices.CoClassAttribute) 
    type.GetCustomAttributes(typeof(System.Runtime.InteropServices.CoClassAttribute), false)[0]; 
var coClass = coClassAttr.CoClass; 

// Instantiate the coclass 
var app = Activator.CreateInstance(coClassAttr.CoClass); 

// If needed, the CLSID is also available: 
var clsid = coClass.GUID; 

je me suis dit ceci en démontant le GAC'd PIA. J'ai remarqué que Outlook.Application était décorée avec un CoClassAttribute, comme ceci:

[ComImport, Guid("00063001-0000-0000-C000-000000000046"), CoClass(typeof(ApplicationClass))] 
public interface Application : _Application, ApplicationEvents_11_Event 
{ 
} 

ApplicationClass ressemble à quelque chose comme:

[ComImport, ClassInterface((short) 0), ComSourceInterfaces("Microsoft.Office.Interop.Outlook.ApplicationEvents_11\0Microsoft.Office.Interop.Outlook.ApplicationEvents\0Microsoft.Office.Interop.Outlook.ApplicationEvents_10\0"), Guid("0006F03A-0000-0000-C000-000000000046"), TypeLibType((short) 11)] 
public class ApplicationClass : _Application, Application, ApplicationEvents_11_Event, ApplicationEvents_Event, ApplicationEvents_10_Event 
{ 
    //... 
} 

Laissez-moi savoir ce que vous pensez tous, donc je peux décider si je dois marquer cela comme la réponse choisie.

Questions connexes