DanielNogales / kodnet

Library and helpers for access to all .NET objects/classes/controls from VFP

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

kodnet

This project only contains the VisualFoxPro related code. If you want the c# code for interop library go to https://github.com/voxsoftware/jxshell.dotnet4

Go to Spanish documentation

Library and helpers for access to all .NET objects/classes/controls from VisualFoxPro 9

Yes made .NET interop easy for VisualFoxPro 9

kodnet adds a small library that allows you to use classes/objects and .NET controls within your VisualFoxPro 9 project. You can call any method, field or property of any .NET class without having to create a COM component. Access the .NET framework components, the large number of free .NET libraries, or your own components from VisualFoxPro 9 without registering or installing anything.

kodnet even allows access to enums, structs, classes and generic methods, which is something you can't achieve by generating a .COM component yourself. kodnet implicitly provides type conversion whenever possible and also provides wrappers that allow you to use native .NET types but not native to VisualFoxPro 9. This is very useful for example with methods that accept byte, float, long, Decimal among others.

Why migrate from wwDotnetBridge to kodnet

kodnet offers advantages not offered by wwDotnetBridge

  • Easier code to write! Call/assign methods, properties, fields using the member's own name.
  • Support to create delegates and add/delete events. YES! kodnet supports DELEGATES without registering VFP components
  • Create generic class instances easily
  • Real support for asynchronous .NET methods
  • Compile C# code dynamically
  • Support for including visual controls from .NET to VFP forms
  • Up to 8 times faster in instance method calls See example

If you are thinking migrating, and need professional help, contact us at our email address above. We will be happy to create an affordable quote to fit your needs.

Want to be a Sponsor?

If you need any specific requirement or want to contribute to this project continue improving you can contact us at contacto@kodhe.com or use the donation link. If you wish to become a sponsor and have your logo/company appear in this README.md, become a sponsor that donates monthly and contact us.

  • Donate to paypal

NET Framework version support

kodnet runs on .NET Framework 4 or higher and any version of Windows that supports this framework and VisualFoxPro 9

Getting started

Load the kodnet environment

* Load kodnet library
do fullpath("kodnet.prg")

If you get a message that says Unable to load CLR it's probably because Windows blocks files downloaded from the Internet. To do this right-click on the .DLL libraries distributed with kodnet and click unlock.

* you can now access to kodnet using _screen.kodnet


local WebClientClass, WebClientObj
* you get a reference to static class calling getStaticWrapper
m.WebClientClass = _screen.kodnet.getStaticWrapper("System.Net.WebClient")
* create an instance of WebClient
m.WebClientObj = m.WebClientClass.construct()
* Download Google's home page
m.WebClientObj.DownloadFile("https://www.google.com", "Sample.html")


* load an assembly by file
local customClass, customObject
_screen.kodnet.loadAssemblyFile("customdotnet.dll")
m.customClass= _screen.kodnet.getStaticWrapper("CustomClass")
* create an instance of type 
m.customObject= m.customClass.construct()
* call customObject's method
? m.customObject.customMethod()


* access to property, methods, fields directly
local int32Class 
m.int32Class= _screen.kodnet.getStaticWrapper("System.Int32")
? m.int32Class.MaxValue
? m.int32Class.MinValue 

Getting started summary

  • Access any .NET component even if it is not marked for interop [ComVisible].
  • You do not need to register or install the component
  • Call any method, property directly like any other object FoxPro
  • Calling the constructor of a class with parameters is possible
  • Call any method overload. kodnet select the best, according to your parameters
  • Support for any non-native .NET type
  • Access to static members, including Structs, Enums, Generics, etc.
  • Access .NET arrays easily using Get and Set methods
  • You can pass an object FoxPro and read it from a .NET method using dynamic.
  • Multithread support
  • Include visual .NET controls within your VisualFoxPro forms and access your members like any other .NET class.
  • Support for adding/deleting .NET event handlers (delegates)
  • Great performance in method calls, properties, because internally it doesn't use Reflection but uses CallSite (the methodology it uses internally dynamic in C#)

How it works

Download the project to see the examples and learn how to use it. It mainly consists of the following

  • ClrHost.dll - Win32 dll to load the .NET runtime
  • DLLs used for interop - The lib folder
  • kodnet.prg - FoxPro prg, frontend to Proxy
  • dotnet4.vcx - FoxPro Visual Class, for adding .NET controls to forms

In a distributed application, it is recommended that you distribute the kodnet components within a folder called kodnet in the same location as your executable.

Take a look at an example of code that uses different features of .NET components

do fullpath("kodnet.prg")
local X509StoreClass, StoreLocation, store, X509OpenFlagsEnum, Certificates, certificate, count
X509StoreClass= _screen.kodnet.getStaticWrapper("System.Security.Cryptography.X509Certificates.X509Store")

* access to enum
StoreLocation= _screen.kodnet.getStaticWrapper("System.Security.Cryptography.X509Certificates.StoreLocation")
store= m.X509StoreClass.construct(StoreLocation.LocalMachine)

* OR use this for certificates only the user
*store= m.X509StoreClass.construct(StoreLocation.CurrentUser)



X509OpenFlagsEnum=  _screen.kodnet.getStaticWrapper("System.Security.Cryptography.X509Certificates.OpenFlags")
m.store.Open(X509OpenFlagsEnum.ReadOnly)

* manage collections  
Certificates= store.Certificates
count= Certificates.Count 

?"Certificates found: " + str(m.count)
FOR i=1 TO m.count 
	* use item for access to collection items
	certificate= m.Certificates.item(m.i - 1)
    if (!ISNULL(m.certificate))
        ? m.certificate.FriendlyName
		? m.certificate.SerialNumber
		? m.certificate.GetName()
    endif 
endfor 

Async and events

Consider now a more advanced example that calls asynchronous methods and uses .NET events.

* KODNET (contacto@kodhe.com)
* Download File asynchronous example

do fullpath("kodnet.prg")

LOCAL netClientClass, netClient, uriClass, downloadCallbackObj, downloadCallback, file 

* select a file
file= GETFILE()
IF EMPTY(m.file)
	RETURN MESSAGEBOX("Please select a file",64,"")
ENDIF 

uriClass= _screen.kodnet.getStaticWrapper("System.Uri")
netClientClass= _screen.kodnet.getStaticWrapper("System.Net.WebClient")
m.netClient= m.netClientClass.construct()





downloadCallbackObj= CREATEOBJECT("downloadCallback")
* create a delegate that point to VisualFoxPro function
downloadCallback=_screen.kodnetManager.createeventhandler(m.downloadCallbackObj, "finished", "System.ComponentModel.AsyncCompletedEventHandler")
* add the event handler 
m.netClient.add_DownloadFileCompleted(m.downloadCallback)

* this method is a .NET async method, this call will complete without finish the download
m.netClient.DownloadFileAsync(uriClass.construct("http://storage-ns01.d0stream.com/.drive/Projects/ffmpeg.tar.gz"), m.file)

* this executes before finish for demostrate that method is called async
? "Download has started. Running in background"
return 


DEFINE CLASS downloadCallback  as Custom 
	FUNCTION finished(sender, args)
		* avoid memory leaks (this is only required for objects not forms)
		this._event.destroy()
		IF !ISNULL(args.Error)
			MESSAGEBOX("Failed download: " + args.Error.Message, 48, "")
		ELSE 
			? "download finished"
			MESSAGEBOX("Finished download.", 64, "")
		ENDIF 
	ENDFUNC 
ENDDEFINE 

Compile C# code

kodnet allow C# code dompilation. Take a look in this example

TEXT TO m.code noshow

using System;
public class program{
	public static void main(){
	}
}
namespace Compiled
{

	public class Person{
		public string name;
		public int age;
	}
	
	public class Test
	{	
		public Person person(string name, int age){
			var p= new Person();
			p.name= name;
			p.age= age;
			return p;
		}
	
		public static int ExecuteFunc(Func<string,int> func)
		{
			return func("Method executed from .NET");
		}
		
		public static int ExecuteFunc(Func<string,int> func, string message)
		{
			return func(message);
		}
		
		public static int ExecuteFunc(Func<string,int,string,int> func, string message, int option, string title)
		{
			return func(message,option,title);
		}
	}
}


ENDTEXT 

LOCAL engine

* COMPILE C# CODE
Local asem, test, person

engine= _screen.kodnet.getStaticWrapper("jxshell.csharplanguage").construct()
m.engine.Runscript(m.code)
asem = m.engine.getCompiledAssembly()
_Screen.kodnet.loadAssembly(m.asem)


* now you can use the type compiled 
test= _screen.kodnet.getStaticWrapper("Compiled.Test").construct()
person= test.person("James", 24)
?person.name
?person.age

Delegates, generic types

kodnet supports the creation of delegates and generic objects. In the following example you will see how the class compiled in the previous example is used, to show the use of delegates and generic types: System.Func<string,int>.

* YES! KODNET SUPPORTS DELEGATES 
LOCAL Func1, Func2, target , TestClass, needrunCompile


TRY 
	* Take a look in compilecsharp.prg example for understand
	TestClass= _screen.kodnet.getStaticWrapper("Compiled.Test")
CATCH TO ex 
	needrunCompile= .t.
ENDTRY 

IF needrunCompile 
	RETURN MESSAGEBOX("Please execute first 'compilecsharp.prg' example",64,"Kodnet")
ENDIF 



target= CREATEOBJECT("func_callback")
Func1= _screen.kodnet.getStaticWrapper("System.Func<System.String,System.Int32>").construct(m.target,"callback")
Func2= _screen.kodnet.getStaticWrapper("System.Func<System.String,System.Int32,System.String,System.Int32>").construct(m.target,"callback")

* Pass Func1 delegate to c# function 
?TestClass.executeFunc(Func1)

* pass overloaded 
?TestClass.executeFunc(Func1, "Parameter sent to c#")


* pass overloaded System.Func<string,int,string,int>
?TestClass.executeFunc(Func2, "Parameter sent to c#", 64, "Title")


* It's a good practice Free delegate, avoid memory leaks
Func1.dispose()
Func2.dispose()

DEFINE CLASS func_callback as Custom 

	FUNCTION callback( str, option, title )
		IF PCOUNT() == 3
			RETURN MESSAGEBOX(str,option,title)
		ELSE 
			RETURN MESSAGEBOX(str)
		ENDIF 

	ENDFUNC 

ENDDEFINE 

About

Library and helpers for access to all .NET objects/classes/controls from VFP

License:Other


Languages

Language:xBase 100.0%