tags:

views:

33

answers:

2

Hello, I'm trying to call Visual Basic's CreateObject method from my C++ code. In VB, I'd simply type:

Dim obj As Object obj = CreateObject("WScript.Network")

And that returns me the object from which I can call more methods. But how can I do that in C++? I'm following the MSDN documentation in http://msdn.microsoft.com/en-us/library/bb776046(v=VS.85).aspx, but those parameters are very obscure and I can't figure them out.

The first parameter is a reference to a CLSID, and I can see from the registry that the CLSID for "WScript.Network" is {093FF999-1EA0-4079-9525-9614C3504B74}. But what's the difference between this parameter and the third one, REFIID?

Thanks in advance!

+1  A: 

First, you probably want to use CoCreateInstance http://msdn.microsoft.com/en-us/library/ms686615%28VS.85%29.aspx, or the equivalent call inside a smart pointer wrapper (eg: CComPtr<>, _com_ptr<>, etc.).

Second, to your specific question, the IID is the interface ID, the CLSID is the class ID. COM objects can have multiple interfaces on the same object in general, which is why there is a distinction (although VB can only see one, which is why you don't need so to specify anything other than the CLSID for VB).

The "correct" way to duplicate what VB is doing is to create the IDispatch interface on the object, and then enumerate the methods using IDispatch. The "better" way in C++ is to create the direct interface you want to use, and call methods directly through it. However, this requires knowing the interface ID (IID, or REFIID passing the struct by reference), which is specific to the other object.

Hope that helps. I can't provide specifics for your particular interface, but maybe this points you in the right direction.

Nick
Thank you! I did some research and I could successfully call my method using COM, as you suggested, using CComPtr and IDispatch. Thanks again!
Luís Mendes
A: 

I'll provide my solution, just for the record. It calls the AddWindowsPrinterConnection to install a network printer. It asks for user confirmation, so if you want to bypass that, you need to set HKEY_CURRENT_USER/Printers/LegacyPointAndPrint/DisableLegacyPointAndPrintAdminSecurityWarning to 1 (you can change it back to 0, after everything is done).

CoInitialize(NULL);
{
    ATL::CComPtr<IDispatch> test;
    _variant_t printerConnection = "\\\\serverAddress\\printerName";
    _variant_t result;
    test.CoCreateInstance(L"WScript.Network");
    test.Invoke1(L"AddWindowsPrinterConnection", &printerConnection, &result);
}

CoUninitialize();
Luís Mendes