October 30, 2025, 10:59:47 AM

News:

IWBasic runs in Windows 11!


New COM Dispatch interface woes

Started by Locodarwin, April 25, 2008, 02:04:14 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Locodarwin

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

Ionic Wind Support Team

I beleive you need to use a registered COM object name, not a path. 

Paul.
Ionic Wind Support Team

Locodarwin

April 25, 2008, 02:18:20 PM #2 Last Edit: April 25, 2008, 02:20:35 PM by Locodarwin
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

Ionic Wind Support Team

dhGetObject is not wrapped, but you can use it directly

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

Ionic Wind Support Team

Locodarwin

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

Locodarwin


Locodarwin

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

sapero

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)

Locodarwin

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