IonicWind Software

IWBasic => General Questions => Topic started by: Locodarwin on April 25, 2008, 02:04:14 PM

Title: New COM Dispatch interface woes
Post by: Locodarwin on April 25, 2008, 02:04:14 PM
Howdy do!

I would expect the following code to produce an object handle.  It doesn't.  I've tried a few variations on a theme with the same NULL results.

Can anyone clear it up?  I'm sure it's some bonehead thing I'm doing or not doing.

IDispatch oWinMan

oWinMan = CreateComObject("winmgmts:\\\\.\\root\\cimv2", "")
If oWinMan = NULL Then
Print "No workie!"
EndIf

PRINT:PRINT "Press any key to close"
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END


Thanks!

-S
Title: Re: New COM Dispatch interface woes
Post by: Ionic Wind Support Team on April 25, 2008, 02:10:51 PM
I beleive you need to use a registered COM object name, not a path. 

Paul.
Title: Re: New COM Dispatch interface woes
Post by: Locodarwin on April 25, 2008, 02:18:20 PM
Quote from: Paul Turley on April 25, 2008, 02:10:51 PM
I beleive you need to use a registered COM object name, not a path. 

Paul.

Here's the beginning of an example from the disphelper library, the file wmi.c from the "samples_c" subfolder:

static LPWSTR getWmiStr(LPCWSTR szComputer)
{
static WCHAR szWmiStr[256];

wcscpy(szWmiStr, L"winmgmts:{impersonationLevel=impersonate}!\\\\");

if (szComputer) wcsncat(szWmiStr, szComputer, 128);
else            wcscat (szWmiStr, L".");

wcscat(szWmiStr, L"\\root\\cimv2");

return szWmiStr;
}


This call's resulting string is used later on in the example to create the object:

dhGetObject(getWmiStr(szComputer), NULL, &wmiSvc)

...so I'm wondering what the equivalent would be for us, as implemented in EBasic.  Replace my called object in my first post to "winmgmts:{impersonationLevel=impersonate}!\\\\" and it still fails to spawn the object (the two strings essentially mean and do the same thing).

-S
Title: Re: New COM Dispatch interface woes
Post by: Ionic Wind Support Team on April 25, 2008, 02:21:38 PM
dhGetObject is not wrapped, but you can use it directly

DECLARE CDECL EXTERN _dhGetObject(WSTRING szProgId, pointer szMachine, pointer ppDisp),int

Title: Re: New COM Dispatch interface woes
Post by: Locodarwin on April 25, 2008, 02:32:48 PM
Okay.  I'm still not sure what's going on here.  Calling the same string in VBS works.  Here's the update using the external function, still not working:

IDispatch oWinMan

DECLARE CDECL EXTERN _dhGetObject(WSTRING szProgId, pointer szMachine, pointer ppDisp),int

_dhGetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2", NULL, &oWinMan)
If oWinMan = NULL Then
Print "No workie!"
Else
Print oWinMan
EndIf

PRINT:PRINT "Press any key to close"
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
Title: Re: New COM Dispatch interface woes
Post by: Locodarwin on April 25, 2008, 02:35:56 PM
Here's a quickie on spawning the Windows Management Instrumentation object:

http://www.microsoft.com/technet/scriptcenter/guide/sas_wmi_jgfx.mspx?mfr=true
Title: Re: New COM Dispatch interface woes
Post by: Locodarwin on April 25, 2008, 03:47:07 PM
Starting to really get to me.  All I'm looking to do is convert a segment of code I've written and tested in VBS.  Here's the segment:

Dim Process, sObject
sObject = "winmgmts:\\.\root\cimv2"
For Each Process in GetObject( sObject ).InstancesOf("win32_process")
If UCase(Process.name) = UCase("program.exe") Then
MsgBox("program.exe is running.")
Exit Function
End If
Next


This is a simple example and I understand how to emulate For Each with a COMENUMBEGIN and COMENUMNEXT.  I just can't get the objects instantiated.

Since the moniker approach doesn't work at all (and should), I've also tried going with the WMI object directly.

The VBS code:

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")


So, this should work:

IDispatch oWinMan, oService
STRING sStringObj

sStringObj = ".ConnectServer(\".\", \"root\\cimv2\")"
Print "Look, this string is correct:"
Print sStringObj
Print
oWinMan = CreateComObject("WbemScripting.SWbemLocator", "")
oService = CallObjectMethod(oWinMan, sStringObj)
If oService = NULL Then
Print "But oService is NULL and it shouldn't be!"
EndIf

PRINT:PRINT "Press any key to close"
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END


...but, no workie!

-S
Title: Re: New COM Dispatch interface woes
Post by: sapero on April 25, 2008, 07:25:09 PM
You need to initialize the library:
DECLARE CDECL EXTERN _dhGetObject(WSTRING szProgId, pointer szMachine, pointer ppDisp),int
DECLARE CDECL EXTERN _dhInitializeImp(int bInitializeCOM, int bUnicode)
DECLARE CDECL EXTERN _dhUninitialize(int bUninitializeCOM)
declare extern _ComEnumNext alias ComEnumNext(comref pEnum),COMREF

IDispatch pService
IDispatch pEnum
IDispatch pProcess
pointer   bstrText

_dhInitializeImp(true, true)


if (_dhGetObject(L"winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2", NULL, &pService))
MessageBox(0, "dhGetObject failed", "")
else
pEnum = ComEnumBegin(pService, ".InstancesOf(%s)", "win32_process")
if (pEnum <> NULL)

pProcess = _ComEnumNext(pEnum)

while (pProcess <> NULL)
GetComProperty(pProcess, "%B", &bstrText, ".name")
print w2s(*<wstring>bstrText)
FreeComString(bstrText)
pProcess->Release()
pProcess = _ComEnumNext(pEnum)
wend

pEnum->Release()
MessageBox(0, "click to close", "")
endif
pService->Release()
endif

_dhUninitialize(true)
Title: Re: New COM Dispatch interface woes
Post by: Locodarwin on April 25, 2008, 08:33:27 PM
Quote from: sapero on April 25, 2008, 07:25:09 PM
You need to initialize the library:
DECLARE CDECL EXTERN _dhGetObject(WSTRING szProgId, pointer szMachine, pointer ppDisp),int
DECLARE CDECL EXTERN _dhInitializeImp(int bInitializeCOM, int bUnicode)
DECLARE CDECL EXTERN _dhUninitialize(int bUninitializeCOM)
declare extern _ComEnumNext alias ComEnumNext(comref pEnum),COMREF

IDispatch pService
IDispatch pEnum
IDispatch pProcess
pointer   bstrText

_dhInitializeImp(true, true)


if (_dhGetObject(L"winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2", NULL, &pService))
MessageBox(0, "dhGetObject failed", "")
else
pEnum = ComEnumBegin(pService, ".InstancesOf(%s)", "win32_process")
if (pEnum <> NULL)

pProcess = _ComEnumNext(pEnum)

while (pProcess <> NULL)
GetComProperty(pProcess, "%B", &bstrText, ".name")
print w2s(*<wstring>bstrText)
FreeComString(bstrText)
pProcess->Release()
pProcess = _ComEnumNext(pEnum)
wend

pEnum->Release()
MessageBox(0, "click to close", "")
endif
pService->Release()
endif

_dhUninitialize(true)


That's fantastic, thank you.  So am I stuck calling the library separate from the new commands for the time being?

-S