Quantcast
Channel: SCN : All Content - All Communities
Viewing all articles
Browse latest Browse all 3184

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)

      } 

    }

 

  #-Function Get-Object-------------------------------------------------

    Function Get-Object {

      param([String] $objectName)

      [Microsoft.VisualBasic.Interaction]::GetObject($objectName)

    }


  #-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)

      $object.GetType().InvokeMember($propertyName,

        [System.Reflection.Bindingflags]::GetProperty,

        $null, $object, $null)

    }

 

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

    Function Set-Property {

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

        $propertyValue)

      [Void] $object.GetType().InvokeMember($propertyName,

        [System.Reflection.Bindingflags]::SetProperty,

        $null, $object, $propertyValue)

    }

 

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

    Function Invoke-Method {

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

        $methodParameters)

      $object.GetType().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.

 

Cheers

Stefan


Viewing all articles
Browse latest Browse all 3184

Trending Articles



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