Jose's Read Only Forum 2023

IT-Consultant: José Roca (PBWIN 10+/PBCC 6+) (Archive only) => COM Programming => Topic started by: José Roca on February 24, 2009, 11:09:37 PM

Title: Calling .NET classes from PowerBASIC
Post by: José Roca on February 24, 2009, 11:09:37 PM
 
To use .NET classes with PowerBASIC you have to register the assembly as a  COM object with the regasm.exe tool.

Quote
The Assembly Registration tool reads the metadata within an assembly and adds the necessary entries to the registry, which allows COM clients to create .NET Framework classes transparently. Once a class is registered, any COM client can use it as though the class were a COM class. The class is registered only once, when the assembly is installed. Instances of classes within the assembly cannot be created from COM until they are actually registered.
http://msdn.microsoft.com/en-us/library/tzat5yw6(VS.71).aspx

The following example creates an instance of the "System.Net.WebClient" class to download a picture from an URI and save it to a file. If system.dll is not still registered in your system, you have to do it first using regasm.exe. Both regasm.exe and system.dll are located in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 in my computer.


' ########################################################################################
' The following example creates an instance of the "System.Net.WebClient" class to
' download a picture from an URI and save it to a file.
' ########################################################################################

#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN () AS LONG

   LOCAL owc AS DISPATCH
   LOCAL vAddress AS VARIANT
   LOCAL vFileName AS VARIANT

   owc = NEWCOM "System.Net.WebClient"

   IF ISOBJECT(owc) THEN
      TRY
         vAddress = "http://www.jose.it-berater.org/webpages_images/h_2.jpg"
         vFileName = EXE.Path$ & "h_2.jpg"
         OBJECT CALL owc.DownloadFile(vAddress, vFileName)
         owc = NOTHING
         MSGBOX "Picture saved"
      CATCH
         IF OBJRESULT = &H80020009 THEN
            MSGBOX "Error &H" & HEX$(IDISPINFO.CODE) & $CRLF & IDISPINFO.DESC$
         ELSE
            MSGBOX "Error &H" & HEX$(OBJRESULT)
         END IF
      END TRY
   END IF

END FUNCTION

Title: Re: Calling .NET classes from PowerBASIC
Post by: Petr Schreiber on February 25, 2009, 03:40:43 PM
Thank you José,

I tried it on PC with .NET 3.5 installed and it worked well.


Petr
Title: Re: Calling .NET classes from PowerBASIC
Post by: Patrice Terrier on February 25, 2009, 03:43:31 PM
José,

I didn't try it yet, but for sure that is a very useful tutorial.

Thank you!

Title: Re: Calling .NET classes from PowerBASIC
Post by: Petr Schreiber on February 25, 2009, 04:30:43 PM
Nice,

not only .NET core libraries, but all "ClassLibraries" created by programmers in MSVS can be called in PB.

If anybody is interested, in MSVS C# 2008 Express you just:

Worked well, tried even returning values. I built it as 3.5 assembly to see if it works just for 2.0, but no problem.
Still not sure how to make methods visible for COM Browser / TypeLibBrowser, but that is detail.

Thanks José, I would never believe it is possible :)


Petr
Title: Re: Calling .NET classes from PowerBASIC
Post by: José Roca on February 25, 2009, 05:10:01 PM
 
Quote
Still not sure how to make methods visible for COM Browser / TypeLibBrowser, but that is detail.

I don't know if it is possible. Unless there is a way unknown to me, it generates dispatch only interfaces that can only be used with late binding. But at least, it works. And TRY/END TRY can be used to catch exceptions, and IDISPINFO can be used to retrieve the error code and description when OBJRESULT returns %DISP_E_EXCEPTION (&H80020009&).
Title: Re: Calling .NET classes from PowerBASIC
Post by: José Roca on February 25, 2009, 06:44:57 PM
 
Well. Apparently you can create dual interfaces adding another attribute to all your public classes:


VB.NET: <ClassInterface(ClassInterfaceType.AutoDual)>
C#:     [ClassInterface(ClassInterfaceType.AutoDual)]

Title: Re: Calling .NET classes from PowerBASIC
Post by: Petr Schreiber on February 25, 2009, 07:08:00 PM
José Roca Rocs again!

Good tip, it works perfectly now.
I can even see ( and use ) methods it inherits from System.Object, such as ToString().
Just have to not forget using ACODE$ for converting string values :)


Thank you,
Petr

Title: Re: Calling .NET classes from PowerBASIC
Post by: José Roca on August 24, 2011, 06:24:57 PM
 
Here is the link for the .NET Framework 4:
http://msdn.microsoft.com/en-us/library/tzat5yw6.aspx

Quote
Just have to not forget using ACODE$ for converting string values

This, of course, no longer applies to PBWIN 10 / PBCC 6, that have native unicode support.
Title: Re: Calling .NET classes from PowerBASIC
Post by: Mike Doty on July 28, 2022, 12:16:04 AM
Automatically register system.dll
Thank you!  Opens up so many possibilities.

#DIM ALL
REM #INCLUDE "win32api.inc" 'for shellexecute
#INCLUDE "shellapi.inc" 'for shellexecute

'http://www.jose.it-berater.org/smfforum/index.php?topic=3053.0
' ########################################################################################
' The following example creates an instance of the "System.Net.WebClient" class to
' download a picture from an URI and save it to a file.
' ########################################################################################

FUNCTION Regasm AS LONG 'only need this code once
  LOCAL sDllPath AS STRING
  sDllPath = "C:\Windows\Microsoft.NET\Framework\v2.0.50727\"
  IF ISFILE(sDllPath + "system.dll") THEN
   SHELL sDLLPath + "regasm.exe system.dll
   FUNCTION = 1 'success
  ELSE
   ? "system.dll not found"
  END IF
END FUNCTION

FUNCTION PBMAIN () AS LONG
   IF RegAsm = 0 THEN EXIT FUNCTION
   LOCAL zFileName AS STRINGZ * 256
   LOCAL owc AS DISPATCH
   LOCAL vAddress AS VARIANT
   LOCAL vFileName AS VARIANT

   owc = NEWCOM "System.Net.WebClient"

   IF ISOBJECT(owc) THEN
      TRY
         vAddress = "http://www.jose.it-berater.org/webpages_images/h_2.jpg"
         vFileName = EXE.PATH$ & "h_2.jpg"
         OBJECT CALL owc.DownloadFile(vAddress, vFileName)
         owc = NOTHING
         'display using default viewer
         zFileName = EXE.PATH$ & "h_2.jpg"
         ShellExecute (%NULL, "OPEN", zFileName, BYVAL %NULL, CURDIR$, %SW_SHOWNORMAL)
      CATCH
         IF OBJRESULT = &H80020009 THEN
            MSGBOX "Error &H" & HEX$(IDISPINFO.CODE) & $CRLF & IDISPINFO.DESC$
         ELSE
            MSGBOX "Error &H" & HEX$(OBJRESULT)
         END IF
      END TRY
   ELSE
     ? "ISOBJECT FAILED"
   END IF
END FUNCTION'