Skip to content
⌘ NSIS Forum Archive

Calling COM object methods from NSIS

4 posts

otrub#

Calling COM object methods from NSIS

Hello everyone 🙂

I tried to make installer for the first time in my life. Installer calls web service on custom page to verify some acivation code. Using MSSOAP dll's and VBS I have result.
But I shouldn't use VBS file.

NSIS
ExecWait "$SYSDIR\cscript.exe //U //NOLOGO $\"$TEMP\soap.vbs$\" $activationCode" $0 
soap.vbs:
On Error Resume Next
Dim Resp
Set objArgs= Wscript.Arguments
Set SOAPClient = createobject("MSSOAP.SoapClient30")
SOAPClient.mssoapinit "http://somesite:80/service?wsdl"
Resp = SOAPClient.QueryForClientIDByNID(objArgs(0))
If Resp = "" Then
WScript.Quit (1)
Else
WScript.Quit (0)
End If

I began to try to understand subject with examples. But it is difficult to me because I've never been C++ programmer.

NSIS
    !define IID_StdOle      '{00020430-0000-0000-C000-000000000046}'
    !define IID_IDispatch   '{00020400-0000-0000-C000-000000000046}'
    !define IID_IUnknown    '{00000000-0000-0000-C000-000000000046}'
    !define IID_NULL        '{00000000-0000-0000-0000-000000000000}'
    !define CLSCTX_SERVER           0x015
    !define LOCALE_SYSTEM_DEFAULT   0x800
 
Section
    DetailPrint "== CLSIDFromProgID =="
    System::Call `Ole32::CLSIDFromProgID(w,&g16)i ("MSSOAP.SoapClient30",.r0).r2`
    DetailPrint "  ERR=$2"
    DetailPrint "  CLSID=$0"
    
    DetailPrint "== CoCreateInstance =="
    System::Call `Ole32::CoCreateInstance(g r0,i 0,i ${CLSCTX_SERVER},g '${IID_IDispatch}',*i .r1) i .r2`
    DetailPrint "  ERR=$2"
    
    
    DetailPrint "== IDispatch::GetTypeInfoCount =="
    System::Call `$1->3(*i .r3)i .r2`
    DetailPrint "  ERR=$2"
    DetailPrint "  $$3=$3"
    
    DetailPrint "== IDispatch::GetTypeInfo =="
    System::Call `$1->4(i 0,i ${LOCALE_SYSTEM_DEFAULT},*g .r3)i .r2`
    DetailPrint "  ERR=$2"
    DetailPrint "  $$3=$3"
    
    DetailPrint "== Oleaut32::SysAllocString =="
    System::Call `Oleaut32::SysAllocString(w "mssoapinit")i .r4`
    DetailPrint "  RC=$4"
    
    DetailPrint "== IDispatch::GetIDsOfNames =="
    System::Call `$1->5(g ${IID_NULL},*i r4,i 1,i ${LOCALE_SYSTEM_DEFAULT},*i .r3)i .r2`
    DetailPrint "  ERR=$2"
    DetailPrint "  $$3=$3"
    DetailPrint "== mssoapinit =="
    System::Call `$1->1(w "http://somesite:80/service?wsdl")t .r2`
    DetailPrint "  mssoapinit=$2"
    
    DetailPrint "== Oleaut32::SysFreeString =="
    System::Call `Oleaut32::SysFreeString(*i r4)`
    
    DetailPrint "== IUnknown::Release =="
    System::Call `$1->2()i .r2`
    DetailPrint "  RefCount=$2" 
SectionEnd 
I don't know whether correctly I make call function
`$1->1(w "http://somesite:80/service?wsdl")t .r2` 
and how to invoke web service method QueryForClientIDByNID.
Give advice how not to use external vbs please. Thanks a lot for att.
otrub#
Originally Posted by Anders View Post
$1->1 is not correct, the method index must be a higher number.
After GetIDsOfNames function operation I received $3 = 1 and thought that it is the index of mssoapinit function. How to find right function number?
Anders#
To go the same path as scripting you would do IDispatch::Invoke. You might be able to use COM directly instead, I'm not familiar with these Soap interfaces so I don't know which approach is the best.