Quantcast
Channel: SCN : All Content - Scripting Languages
Viewing all articles
Browse latest Browse all 522

How To Use COM Functions in PowerShell Easily, in Comparison with VBScript, Using the Example of CCo

$
0
0

Hello community,

 

over two years ago I presented COM Connector (CCo) here - CCo makes the using of the NetWeaver RFC library very easy.

Slowly but surely the landscape of the script language environments changed in Windows OS - from Windows Script Host (WSH) to PowerShell. From this point of view it seems good to take also a movement.

 

Here a PowerShell example how to get all installed SAP components and its version numbers in comparison with a VBScript which offers the same information.

 

#-Begin-----------------------------------------------------------------


  #-Constants-----------------------------------------------------------

    $RFC_OK = 0

    $VarByRef = -1


  #-Includes------------------------------------------------------------

    ."Includes\COM.ps1"

 

  #-Function Get-SAPComponents------------------------------------------

    Function Get-SAPComponents {

 

      $SAP = $null

      $SAP = Create-Object "COMNWRFC"

      if ($SAP -eq $null) {

        Break

      }

 

      $hRFC = Invoke-Method $SAP "RfcOpenConnection" @(

        "ASHOST=NSP, SYSNR=00, CLIENT=001, USER=BCUSER")

      if ($hRFC -eq 0) {

        Free-Object $SAP

        Break

      }

 

      $hFuncDesc = Invoke-Method $SAP "RfcGetFunctionDesc" @(

        $hRFC, "DELIVERY_GET_INSTALLED_COMPS")

      if ($hFuncDesc -eq 0) {

        $rc = Invoke-Method $SAP "RfcCloseConnection" $hRFC

        Free-Object $SAP

        Break

      }

 

      $hFunc = Invoke-Method $SAP "RfcCreateFunction" $hFuncDesc

      if ($hFunc -eq 0) {

        $rc = Invoke-Method $SAP "RfcCloseConnection" $hRFC

        Free-Object $SAP

        Break

      }

 

      $rc = Invoke-Method $SAP "RfcInvoke" @($hRFC, $hFunc)

      if ($rc -eq $RFC_OK) {

 

        $rc = Invoke-Method $SAP "RfcGetTable" @(

          $hFunc, "TT_COMPTAB", $VarByRef)

        if ($rc -eq $RFC_OK) {

 

          $hTable = Get-Property $SAP "lngByRef"

          $rc = Invoke-Method $SAP "RfcGetRowCount" @(

            $hTable, $VarByRef)

          $RowCount = Get-Property $SAP "lngByRef"

 

          $rc = Invoke-Method $SAP "RfcMoveToFirstRow" $hTable

 

          for ($i = 1; $i -le $RowCount ; $i++) {

 

            $Row = Invoke-Method $SAP "RfcGetCurrentRow" $hTable

 

            $rc = Invoke-Method $SAP "RfcGetChars" @(

              $Row, "COMPONENT", $VarByRef, 30)

            $charBuffer = Get-Property $SAP "strByRef"

            $txt = $txt + $charBuffer

 

            $rc = Invoke-Method $SAP "RfcGetChars" @(

              $Row, "RELEASE", $VarByRef, 10)

            $charBuffer = Get-Property $SAP "strByRef"

            $txt = $txt + $charBuffer

 

            $rc = Invoke-Method $SAP "RfcGetChars" @(

              $Row, "EXTRELEASE", $VarByRef, 10)

            $charBuffer = Get-Property $SAP "strByRef"

            $txt = $txt + $charBuffer

 

            $rc = Invoke-Method $SAP "RfcGetChars" @(

              $Row, "COMP_TYPE", $VarByRef, 1)

            $charBuffer = Get-Property $SAP "strByRef"

            $txt = $txt + $charBuffer + "`r`n"

 

            if ($i -lt $RowCount) {

              $rc = Invoke-Method $SAP "RfcMoveToNextRow" $hTable

            }

 

          }

        }

      }

 

      $rc = Invoke-Method $SAP "RfcDestroyFunction" $hFunc

      $rc = Invoke-Method $SAP "RfcCloseConnection" $hRFC

      Free-Object $SAP

      Remove-Variable SAP

      $txt

    }

 

  #-Function Main-------------------------------------------------------

    Function Main {

      $Components = Get-SAPComponents

      Write-Host $Components

    }

 

  #-Main----------------------------------------------------------------

    Main

 

#-End-------------------------------------------------------------------

 

 

Here now the VBScript:

 

'-Begin-----------------------------------------------------------------

 

  '-Directives----------------------------------------------------------

    Option Explicit

 

  '-Constants-----------------------------------------------------------

    Const RFC_OK = 0

 

  '-Function GetSAPComponents-------------------------------------------

    Function GetSAPComponents()

 

      '-Variables-------------------------------------------------------

        Dim SAP, hRFC, rc, hFuncDesc, hFunc, hTable, RowCount, i, Row

        Dim charBuffer, strText

 

      Set SAP = CreateObject("COMNWRFC")

      If Not IsObject(SAP) Then

        Exit Function

      End If

 

      hRFC = SAP.RfcOpenConnection("ASHOST=NSP, SYSNR=00, " & _

        "CLIENT=001, USER=BCUSER")

      If hRFC = 0 Then

        Set SAP = Nothing

        Exit Function

      End If

 

      hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, _

        "DELIVERY_GET_INSTALLED_COMPS")

      If hFuncDesc = 0 Then

        rc = SAP.RfcCloseConnection(hRFC)

        Set SAP = Nothing

        Exit Function

      End If

 

      hFunc = SAP.RfcCreateFunction(hFuncDesc)

      If hFunc = 0 Then

        rc = SAP.RfcCloseConnection(hRFC)

        Set SAP = Nothing

        Exit Function

      End If

 

      If SAP.RfcInvoke(hRFC, hFunc) = RFC_OK Then

        If SAP.RfcGetTable(hFunc, "TT_COMPTAB", hTable) = RFC_OK Then

          rc = SAP.RfcGetRowCount(hTable, RowCount)

          rc = SAP.RfcMoveToFirstRow(hTable)

          For i = 1 To RowCount

            Row = SAP.RfcGetCurrentRow(hTable)

            rc = SAP.RfcGetChars(Row, "COMPONENT", charBuffer, 30)

            strText = strText & Trim(charBuffer) & " "

            rc = SAP.RfcGetChars(Row, "RELEASE", charBuffer, 10)

            strText = strText & Trim(charBuffer) & " "

            rc = SAP.RfcGetChars(Row, "EXTRELEASE", charBuffer, 10)

            strText = strText & Trim(charBuffer) & " "

            rc = SAP.RfcGetChars(Row, "COMP_TYPE", charBuffer, 1)

            strText = strText & Trim(charBuffer) & vbCrLf

            If i < RowCount Then

              rc = SAP.RfcMoveToNextRow(hTable)

            End If

          Next

        End If

      End If

 

      rc = SAP.RfcDestroyFunction(hFunc)

      rc = SAP.RfcCloseConnection(hRFC)

      Set SAP = Nothing

 

      GetSAPComponents = strText

    End Function

 

  '-Sub Main------------------------------------------------------------

    Sub Main()

      MsgBox GetSAPComponents()

    End Sub

 

  '-Main----------------------------------------------------------------

    Main

 

'-End-------------------------------------------------------------------

 

 

As you can see it is very comparable.

 

To establish the comparibility I use an include file, which stores the COM access routines like Create-Object, Invoke-Method etc.

 

#-Begin-----------------------------------------------------------------

 

  #-Function Create-Object----------------------------------------------

    Function Create-Object {

      param([String] $objectName)

      try {

        New-Object -ComObject $objectName

      }

      catch {

        [Void] [System.Windows.Forms.MessageBox]::Show(

          "Can't create object", "Important hint", 0)

      } 

    }

 

  #-Sub Free-Object-----------------------------------------------------

    Function Free-Object {

      param([__ComObject] $object)

      [Void] [System.Runtime.Interopservices.Marshal]::ReleaseComObject($object)

    }

 

  #-Function Get-Property-----------------------------------------------

    Function Get-Property {

      param([__ComObject] $object, [String] $propertyName)

      $objectType = [System.Type]::GetType($object)

      $objectType.InvokeMember($propertyName,

        [System.Reflection.Bindingflags]::GetProperty,

        $null, $object, $null)

    }

 

  #-Sub Set-Property----------------------------------------------------

    Function Set-Property {

      param([__ComObject] $object, [String] $propertyName,

        $propertyValue)

      $objectType = [System.Type]::GetType($object)

      [Void] $objectType.InvokeMember($propertyName,

        [System.Reflection.Bindingflags]::SetProperty,

        $null, $object, $propertyValue)

    }

 

  #-Function Invoke-Method----------------------------------------------

    Function Invoke-Method {

      param([__ComObject] $object, [String] $methodName,

        $methodParameters)

      $objectType = [System.Type]::GetType($object)

      $objectType.InvokeMember($methodName,

        [System.Reflection.Bindingflags]::InvokeMethod,

        $null, $object, $methodParameters, $null, $null, $null)

    }

 

#-End-------------------------------------------------------------------

 

001.jpg

 

With this tiny include you can use COM functions in PowerShell almost like in VBScript.

 

Let the games begin.

 

 

2016/03/08:

Minor changes for PowerShell 5 compatibility.

 

 

Cheers

Stefan


Viewing all articles
Browse latest Browse all 522

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>