📜 ⬆️ ⬇️

CEF, ES6, Angular 2, TypeScript using .Net Core classes. Creating a cross-platform GUI for .Net using CEF

Everyone asks me - "Why is this necessary?". To which, I proudly reply - “I use 1C to access the trading equipment, Web services via ws-protocols, ready-made components. 1C, Linux, Excel, Word, OpenXML, ADO and Net Core . In addition, I will make the transfer of JS objects to the .Net side using DynamicObject.

You can make a specific CEF configuration for all platforms and you can make cross-platform dextup applications. As an analogue of Electron. .Net Core develops and you can quite easily transfer applications under WPF and UWP to Angular 2 by making a description of the classes and using IntelliSense when encoding to TypeScript.

But I understand perfectly well that these are just lofty words, and very few people need it. But I'm damn interested, especially after programming on 1C.

To show the possibilities, take an example from my article Cross-Platform Using .Net Classes in 1C via Native VK. Or replacing COM with Linux II .
')
It has a lot of sugar and shows all the problems. Immediately I apologize for Ruslish. I try very hard, but I have a lot of examples on it, and there is very little time.

 //  
    //IConfiguration WithDefaultLoader(this IConfiguration configuration, Action<LoaderSetup> setup = null, IEnumerable<IRequester> requesters = null);
    var config = Configuration.Default.WithDefaultLoader();
    //    
    var address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes";
    //     
 
    // 
    //Task<IDocument> OpenAsync(this IBrowsingContext context, string address);
    var document = BrowsingContext.New(config).OpenAsync(address).Result;
    //  CSS         
    var rowSelector = "tr.vevent";
    var  = document.QuerySelectorAll<IHtmlTableRowElement>(rowSelector);
    foreach (var str in )

TypeScript :

            let Net = NetObject.NetWrapper;
            let $$ = NetObject.FlagDeleteObject; //         

            //   AngleSharp
            let AngleSharp = Net.("AngleSharp");
            //     
            let Configuration = AngleSharp.GetType("AngleSharp.Configuration");
            let BrowsingContext = AngleSharp.GetType("AngleSharp.BrowsingContext");
            let HtmlParser = AngleSharp.GetType("AngleSharp.Parser.Html.HtmlParser");
            let IHtmlTableRowElement = AngleSharp.GetType("AngleSharp.Dom.Html.IHtmlTableRowElement");
            let ApiExtensions = AngleSharp.GetType("AngleSharp.Extensions.ApiExtensions");

            let Default = Configuration._Default;
            var config = Default.WithDefaultLoader();
            //    
            var address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes";
            //     

            let Context = BrowsingContext.New(config);

            // 
            //Task<IDocument> OpenAsync(this IBrowsingContext context, string address);
            let document = await Context.async.OpenAsync(address);
            //        Proxy  Target fuction
            //      
            document = NetObject.WrapResult(document, true);

            //  CSS         
            let rowSelector = "tr.vevent";

            //          
            //let rows = document.QuerySelectorAll([IHtmlTableRowElement], rowSelector);
           
            //    
            //IEnumerable < TElement > QuerySelectorAll<TElement>(this IParentNode parent, string selectors) where TElement : IElement;
             let rows = ApiExtensions.QuerySelectorAll([IHtmlTableRowElement], document, rowSelector);
         
            //    ,     
            //let rows = document.QuerySelectorAll(rowSelector);

//      
            for (let row of rows) {
                let Cells = row._Cells;
                let i = 0;
                let  = new ();
                this.ResultParse.push();
//       
                for (let Cell of Cells) {
 //    ,      
                    if (i < 8)                        {
                    [this.Colums[i]] = Cell._TextContent;
                    Cell($$); //      
                    i++;
                    }
                }
                Cells($$);
                row($$);
            }
            rows($$);

            //    
            NetObject.DeleteNetObjets(AngleSharp, Configuration, BrowsingContext, HtmlParser, IHtmlTableRowElement, ApiExtensions, Default, config, Context, document); 
            alert("    "+Net.());

C#. "_"

let Default = Configuration._Default;

async:

let document = await Context.async.OpenAsync(address);

, :

let rows = ApiExtensions.QuerySelectorAll([IHtmlTableRowElement], document, rowSelector);

, .Net

Cells(NetObject.FlagDeleteObject);
Cells($$);

Intel Core i3-2120 CPU 3.3 GHz.

Proxy 60
Proxy 45k
160k

- .

.

 public class 
    {
       public string  { get; set; }
       public  (string )
            {
            this. = ;
            }
 public object ExpandoObject()
        {

            dynamic res = new ExpandoObject();
            res. = " ExpandoObject";
            res. = 456;
            res. = (Func<string>)(() => res.);
            res. = (Func<int, int, int>)((x, y) => x + y);

            return res;
        }
     }

TypeScript :

//        
let  = Net.GetType("TestDllForCoreClr.", "TestDllForCoreClr");
//    new
let TO = new ("  ");
//  ExpandoObject
var EO = TO.ExpandoObject();
let =EO._;//   _
let =EO._;
let  = EO._;
let res= ());//   
 //  ExpandoObject    
 res= EO.());//  ExpandoObject

. .Net . IDispatch Linux. CEF :

   declare var window: WindowInterface;
    export interface WindowInterface {
    CallNetMethod(Id: number, MethodName: string, args?: any[]): any;//  
    CallNetDelegate(Id: number, args?: any[]): any; //  
    CallNetPropertySet(Id: number, PropertyName: string, value: any): void; //  
    CallNetPropertyGet(Id: number, PropertyName: string): any; //   
    DeleteNetObject(Id: number): void; //       .Net
    //     Task  Task<T>
    CallAsyncNetObjectFunction(Id: number, MethodName: string, TaskId: string, args?: any[]): any; 
    //     CEF,    Promise 
    RegisterCallBacks(SetAsyncResult: (Successfully: boolean, TaskId: string, result: any) => void): void; 
    //       
    CallNetObjectGenericFunction(Id: number, MethodName: string, types: any[], args?: any[]): any;
    //   IEnumerator MoveNext   .Net
    IteratorNext(Id: number): any;
}

Target :

export interface NetObjectinterface {
    (): void;
    Id: number;
    isNetObject: boolean;
    IsAsyncCall?: boolean;
    CallAsProp(target: NetObject, name: any): ResultCallAsProp;
    Execute: (target: NetObject, name: any, args: any[]) => any;

}

Target new (). Handler:

export var NetObjectHandler: ProxyHandler<NetObjectinterface> = {
    get: (target, name: any) => {
//   PropertyGet      
//         "_"

        let res = target.CallAsProp(target, name);
        if (res.Successfully)
            return res.result;

        return (...args: any[]) => {
            return target.Execute(target, name, args);
        }

    },
    set: function (target, prop, value, receiver) {
        return NetObject.SetPropertyValue(target, prop, value, receiver);
    },

    apply: (target, that, args) => {
        if (args.length == 1) {
            var param = args[0];
            if (param === NetObject.FlagGetObject)
                return target;
            else if (param === NetObject.FlagDeleteObject) {
                window.DeleteNetObject(target.Id);
                return undefined;
            }
        }

        NetObject.SetArgs(args);
        let res = window.CallNetDelegate(target.Id, args)
        return NetObject.WrapResult(res, true);
    },

    construct: (target, argumentsList, newTarget) => {
//     Net 
// object (object , params object[] argOrig)
        NetObject.SetArgs(argumentsList);
        argumentsList.unshift(target);
        let res = window.CallNetMethod(0, "", argumentsList);
        return NetObject.WrapResult(res, true);

    }
}

Target:

function getNetObject(id: number): NetObjectinterface {
    let netObject = <NetObjectinterface>function (start: number) { };
    netObject.Id = id;
    netObject.isNetObject = true;
    netObject[NetObject.isNetclass] = true;
    netObject.Execute = NetObject.Execute;
    netObject.CallAsProp = NetObject.CallAsProp;
    return netObject;
}

CEF :

static WrapResult(value: any, ReturnProxy: boolean = false): any {
        if (typeof value == "object") {
            if ("IsNetObject" in value) {
                let res = getNetObject(value.Id);
                if (ReturnProxy)
                    return new Proxy(res, NetObjectHandler);
                else
                    return res

            }


        }
        return value;
    }

:

static GetPromise(Target: NetObjectinterface, name: any, args: any[]) {

        let key = window.CallNetMethod(0, "GetUniqueString");
        let promise = new Promise((resolve, reject) => {
            NetObject.PromiseDictioanary.set(key, { resolve: resolve, reject: reject });
            window.CallAsyncNetObjectFunction(Target.Id, name, key, args);
        });
        return promise;
    }

:

 static SetPromiseResult(Successfully: boolean, TaskId: string, result: any) {
        let item = NetObject.PromiseDictioanary.get(TaskId);
        try {

            NetObject.PromiseDictioanary.delete(TaskId);
           //       Proxy  Target function
            //  result = NetObject.WrapResult(result, true);
           //   "  then"
            if (Successfully)
                item.resolve(result);
            else
                item.reject(result);
        }

        catch (e) {
            item.reject("    " + e);
            alert("    " + e);
        }
    }

:

 static PromiseDictioanary = new Map();

:

NetProxy
declare var window: WindowInterface;
declare var $_: Symbol;
declare var _$: Symbol;

export interface WindowInterface {
    CallNetMethod(Id: number, MethodName: string, args?: any[]): any;//  
    CallNetDelegate(Id: number, args?: any[]): any; //  
    CallNetPropertySet(Id: number, PropertyName: string, value: any): void; //  
    CallNetPropertyGet(Id: number, PropertyName: string): any; //   
    DeleteNetObject(Id: number): void; //       .Net
    //     Task  Task<T>
    CallAsyncNetObjectFunction(Id: number, MethodName: string, TaskId: string, args?: any[]): any; 
    //     CEF,    Promise 
    RegisterCallBacks(SetAsyncResult: (Successfully: boolean, TaskId: string, result: any) => void): void; 
    //       
    CallNetObjectGenericFunction(Id: number, MethodName: string, types: any[], args?: any[]): any;
    //   IEnumerator MoveNext   .Net
    IteratorNext(Id: number): any;
}

class ResultCallAsProp {
    constructor(public Successfully: boolean, public result?: any) { };
}
export interface NetObjectinterface {
    (): void;
    Id: number;
    isNetObject: boolean;
    IsAsyncCall?: boolean;
    CallAsProp(target: NetObject, name: any): ResultCallAsProp;
    Execute: (target: NetObject, name: any, args: any[]) => any;

}

export var NetObjectHandler: ProxyHandler<NetObjectinterface> = {
    get: (target, name: any) => {


        let res = target.CallAsProp(target, name);
        if (res.Successfully)
            return res.result;

        return (...args: any[]) => {
            return target.Execute(target, name, args);
        }


    },
    set: function (target, prop, value, receiver) {
        return NetObject.SetPropertyValue(target, prop, value, receiver);
    },

    apply: (target, that, args) => {
        if (args.length == 1) {
            var param = args[0];
            if (param === NetObject.FlagGetObject)
                return target;
            else if (param === NetObject.FlagDeleteObject) {
                window.DeleteNetObject(target.Id);
                return undefined;
            }
        }

        NetObject.SetArgs(args);
        let res = window.CallNetDelegate(target.Id, args)
        return NetObject.WrapResult(res, true);
    },

    construct: (target, argumentsList, newTarget) => {

        //  var res = NetObject.GetNetObject(5);
        //  return new Proxy(res, NetObjectHandler)
        NetObject.SetArgs(argumentsList);
        argumentsList.unshift(target);
        let res = window.CallNetMethod(0, "", argumentsList);
        return NetObject.WrapResult(res, true);

    }


}

function getNetObject(id: number): NetObjectinterface {
    let netObject = <NetObjectinterface>function (start: number) { };
    netObject.Id = id;
    netObject.isNetObject = true;
    netObject[NetObject.isNetclass] = true;
    netObject.Execute = NetObject.Execute;
    netObject.CallAsProp = NetObject.CallAsProp;
    return netObject;
}

function GetNetProxy(): any {
    let res = getNetObject(0);
    if (NetObject.FlagFirstLoad) {
        try {
            window.RegisterCallBacks(NetObject.SetPromiseResult);

        }
        catch (e) {
            // alert(" " + e);
        }

        NetObject.FlagFirstLoad = false;
    }

    return new Proxy(res, NetObjectHandler);

}
export class NetObject {
    static GetNetObject(id: number) { return getNetObject(id); }
    static isNetclass = Symbol();
    static IsAsyncCall = Symbol();
    static FlagGetObject = Symbol();
    static FlagDeleteObject = Symbol();
    static FlagFirstLoad = true;
    static NetWrapper = GetNetProxy();

    static PromiseDictioanary = new Map();
    static GetIterator(target: NetObjectinterface): any {
        return function () {
            let IdIterator = window.CallNetMethod(0, "GetIterator", [target]).Id;

            return {
                next: function () {

                    let value = window.IteratorNext(IdIterator);
                    if (value === undefined) {
                        return { value: undefined, done: true };

                    } else
                        return { value: NetObject.WrapResult(value, true), done: false }

                }
            }


        }
    }


    static WrapResult(value: any, ReturnProxy: boolean = false): any {
        if (typeof value == "object") {
            if ("IsNetObject" in value) {
                let res = getNetObject(value.Id);
                if (ReturnProxy)
                    return new Proxy(res, NetObjectHandler);
                else
                    return res

            }


        }
        return value;
    }

    static WrapObject(value: any): any {
        if (typeof value == "function") {
            if (NetObject.isNetclass in value)
                return new Proxy(value, NetObjectHandler);
        }
    }

    static GetPropertyValue(target: NetObjectinterface, name: any): any {
        let res = window.CallNetPropertyGet(target.Id, name);
        return NetObject.WrapResult(res, true);

    }

    static SetPropertyValue(target: NetObjectinterface, prop: any, value: any, receiver: any): any {
        let res = window.CallNetPropertySet(target.Id, prop, NetObject.GetTarget(value));
        return true;

    }

    static CallAsProp(Target: NetObjectinterface, name: any): ResultCallAsProp {
        if (name === Symbol.iterator) {
            return new ResultCallAsProp(true, NetObject.GetIterator(Target));
        }

        if (name === Symbol.toPrimitive) {
            return new ResultCallAsProp(true, () => { return `Id= ${Target.Id}, isNetObject= ${Target.isNetObject}` });
        }
        if (name.startsWith('_')) {

            return new ResultCallAsProp(true, NetObject.GetPropertyValue(Target, name.substring(1)));

        }

        if (name === "async") {

            let res = getNetObject(Target.Id);

            res.Execute = NetObject.ExecuteAsync;
            res.CallAsProp = NetObject.CallAsPropAsync;
            return new ResultCallAsProp(true, new Proxy(res, NetObjectHandler));
        }

        return new ResultCallAsProp(false);
    }

    static CallAsPropAsync(Target: NetObjectinterface, name: any): ResultCallAsProp {


        return new ResultCallAsProp(false);
    }

    static GetPromise(Target: NetObjectinterface, name: any, args: any[]) {

        let key = window.CallNetMethod(0, "GetUniqueString");
        let promise = new Promise((resolve, reject) => {
            NetObject.PromiseDictioanary.set(key, { resolve: resolve, reject: reject });
            window.CallAsyncNetObjectFunction(Target.Id, name, key, args);
        });
        return promise;
    }

    static GetTarget(obj: any): any {
        if (typeof obj == "function") {
            if (NetObject.isNetclass in obj)
                return obj(NetObject.FlagGetObject);


        }
        return obj;
    }

    static SetArgs(args: any[]) {
        for (let i in args) {
            let obj = args[i];
            if (typeof obj == "function") {
                if (NetObject.isNetclass in obj)
                    args[i] = obj(NetObject.FlagGetObject);


            }

        }
    }


    static SetPromiseResult(Successfully: boolean, TaskId: string, result: any) {
        let item = NetObject.PromiseDictioanary.get(TaskId);
        try {

            NetObject.PromiseDictioanary.delete(TaskId);
            //  result = NetObject.WrapResult(result, true);
            if (Successfully)
                item.resolve(result);
            else
                item.reject(result);
        }

        catch (e) {
            item.reject("    " + e);
            alert("    " + e);
        }
    }

    static CheckGenericMethod(args: any[]): any {

        var argsCount = args.length;

        if (argsCount > 0 && args[0] instanceof Array) {
            var types = args[0].slice();
            NetObject.SetArgs(types);

            var args2 = args.slice(1);
            NetObject.SetArgs(args2);
            return { IsGeneric: true, types: types, args: args2 }
        }

        return { IsGeneric: false };

    }
    static Execute(Target: NetObjectinterface, name: any, args: any[]) {

        let res = undefined;
        let chek = NetObject.CheckGenericMethod(args);

        if (chek.IsGeneric) {
            res = window.CallNetObjectGenericFunction(Target.Id, name, chek.types, chek.args);

        }
        else {
            NetObject.SetArgs(args);

            res = window.CallNetMethod(Target.Id, name, args);
        }

        return NetObject.WrapResult(res, true);
    }

    static ExecuteAsync(Target: NetObjectinterface, name: any, args: any[]) {


        let res = undefined;
        let chek = NetObject.CheckGenericMethod(args);

        if (chek.IsGeneric) {
            let Target0 = getNetObject(0);
            let task = window.CallNetObjectGenericFunction(Target.Id, name, chek.types, chek.args);
            res = NetObject.GetPromise(Target0, "ReturnParam", [getNetObject(task.Id)]);
            window.DeleteNetObject(task.Id);

        }
        else {
            NetObject.SetArgs(args);

            res = NetObject.GetPromise(Target, name, args);
        }

        return res;
    }

    static New(Target: NetObjectinterface, name: any, args: any[]): any {
        NetObject.SetArgs(args);
        var res = window.CallNetMethod(0, "", args);
        return NetObject.WrapResult(res, true);
    }

    static DeleteNetObjets(...args: any[]) {

        for (let item of args)
            item(NetObject.FlagDeleteObject);
    }


}


++. , , .
Dev Tools CefSimple:

CEF JS .Net Core
#include "include/CEF_V8.H"
#include "ManagedDomainLoader.h"
#include "CefV8HandlersForNet.h"

#include "types.h"
#include "NetConverter.h"


#include "include/base/cef_bind.h"
#include "include/wrapper/cef_closure_task.h"
#include <thread>
#include "include/base/cef_platform_thread.h"
namespace NetObjectToNative{

	BaseClassForNetHandlers::BaseClassForNetHandlers(ManagedDomainLoader* mD)
	{
		this->mD = mD;
	}

	 bool CallNetObjectFunction::Execute(const CefString& name,
		CefRefPtr<CefV8Value> object,
		const CefV8ValueList& arguments,
		CefRefPtr<CefV8Value>& retval,
		CefString& exception)  {


		const size_t argumentsCount = arguments.size();
		vector<wstring> savedstrings;
		NetObjectToNative::tVariant* Params = nullptr;

		int Target = arguments[0]->GetIntValue();
		wstring MethodMame = arguments[1]->GetStringValue().ToWString();

		CefRefPtr<CefV8Value> params;

		size_t  argCount = 0;
		if (argumentsCount == 3)
		{


			params = arguments[2];

			if (!params->IsArray())
			{
				exception = CefString(L"   3    ");
				return true;

			}
			argCount = params->GetArrayLength();


		}

		if (argCount > 0)
		{
			savedstrings.reserve(argCount);
			Params = new NetObjectToNative::tVariant[argumentsCount];
			NetObjectToNative::tVariant* Param = Params;

			for (size_t i = 0; i < argCount; ++i)
			{

				NetObjectToNative::ConvertCEFtoNet(params->GetValue(i), &Param[i], savedstrings);
			}

		}
		wchar_t*  Error = nullptr;
		NetObjectToNative::tVariant RetVal;

		bool res = mD->pCallAsFunc(Target, MethodMame.c_str(), &RetVal, Params, argCount, &Error);

		if (res)
		{

			retval = NetObjectToNative::ConvertNetToCef(&RetVal, true);
		}
		else
		{
			if (Error)
				exception = CefString(std::wstring(Error));
			delete Error;
		}

		if (Params) delete[] Params;

		return true;
	}

	 //====================== ============================================
	 bool CallAsyncNetObjectFunction::Execute(const CefString& name,
		 CefRefPtr<CefV8Value> object,
		 const CefV8ValueList& arguments,
		 CefRefPtr<CefV8Value>& retval,
		 CefString& exception) {


		 const size_t argumentsCount = arguments.size();
		 vector<wstring> savedstrings;
		 NetObjectToNative::tVariant* Params = nullptr;

		 int Target = arguments[0]->GetIntValue();
		 wstring MethodMame = arguments[1]->GetStringValue().ToWString();
		 wstring TaskId = arguments[2]->GetStringValue().ToWString();

		 CefRefPtr<CefV8Value> params;

		 size_t  argCount = 0;
		 if (argumentsCount == 4)
		 {


			 params = arguments[3];

			 if (!params->IsArray())
			 {
				 exception = CefString(L"    4    ");
				 return true;

			 }
			 argCount = params->GetArrayLength();


		 }

		 if (argCount > 0)
		 {
			 savedstrings.reserve(argCount);
			 Params = new NetObjectToNative::tVariant[argumentsCount];
			 NetObjectToNative::tVariant* Param = Params;

			 for (size_t i = 0; i < argCount; ++i)
			 {

				 NetObjectToNative::ConvertCEFtoNet(params->GetValue(i), &Param[i], savedstrings);
			 }

		 }
		 wchar_t*  Error = nullptr;
		 NetObjectToNative::tVariant RetVal;

		 //bool res = mD->pCallAsFunc(Target, MethodMame.c_str(), &RetVal, Params, argCount, &Error);
		 bool res = mD->pCallAsyncFunc(Target, MethodMame.c_str(), this->cfn, TaskId.c_str(), Params, argCount, &Error);

		 if (res)
		 {

			 retval = NetObjectToNative::ConvertNetToCef(&RetVal, true);
		 }
		 else
		 {
			 if (Error)
				 exception = CefString(std::wstring(Error));
			 delete Error;
		 }

		 if (Params) delete[] Params;

		 return true;
	 }

	//============================ Call Generic Function

	 bool CallNetObjectGenericFunction::Execute(const CefString& name,
		 CefRefPtr<CefV8Value> object,
		 const CefV8ValueList& arguments,
		 CefRefPtr<CefV8Value>& retval,
		 CefString& exception) {


		 const size_t argumentsCount = arguments.size();
		 vector<wstring> savedstrings;
		 NetObjectToNative::tVariant* Params = nullptr;
		 NetObjectToNative::tVariant* ParamsTypes = nullptr;

		 int Target = arguments[0]->GetIntValue();
		 wstring MethodMame = arguments[1]->GetStringValue().ToWString();

		 CefRefPtr<CefV8Value> params;
		 CefRefPtr<CefV8Value> types= arguments[2];
		 size_t  typesCount= types->GetArrayLength();


		 size_t  argCount = 0;
		 if (argumentsCount == 4)
		 {


			 params = arguments[3];

			 if (!params->IsArray())
			 {
				 exception = CefString(L"   4    ");
				 return true;

			 }
			 argCount = params->GetArrayLength();


		 }

		 
		 savedstrings.reserve(argCount+ typesCount);
		 ParamsTypes = new NetObjectToNative::tVariant[typesCount];
		 for (size_t i = 0; i < typesCount; ++i)
		 {

			 NetObjectToNative::ConvertCEFtoNet(types->GetValue(i), &ParamsTypes[i], savedstrings);
		 }


		 if (argCount > 0)
		 {
			
			 Params = new NetObjectToNative::tVariant[argumentsCount];
			 NetObjectToNative::tVariant* Param = Params;

			 for (size_t i = 0; i < argCount; ++i)
			 {

				 NetObjectToNative::ConvertCEFtoNet(params->GetValue(i), &Param[i], savedstrings);
			 }

		 }



		 wchar_t*  Error = nullptr;
		 NetObjectToNative::tVariant RetVal;

		 bool res = mD->pCallAsGenericFunc(Target, MethodMame.c_str(), &RetVal, ParamsTypes, typesCount, Params, argCount, &Error);

		 if (res)
		 {

			 retval = NetObjectToNative::ConvertNetToCef(&RetVal, true);
		 }
		 else
		 {
			 if (Error)
				 exception = CefString(std::wstring(Error));
			 delete Error;
		 }

		 if (Params) delete[] Params;
		 delete[] ParamsTypes;

		 return true;
	 }


	 //===================== CallNetDelegate

	 bool CallNetDelegate::Execute(const CefString& name,
		 CefRefPtr<CefV8Value> object,
		 const CefV8ValueList& arguments,
		 CefRefPtr<CefV8Value>& retval,
		 CefString& exception) {


		 const size_t argumentsCount = arguments.size();
		 vector<wstring> savedstrings;
		 NetObjectToNative::tVariant* Params = nullptr;

		 int Target = arguments[0]->GetIntValue();
		

		 CefRefPtr<CefV8Value> params;

		 size_t  argCount = 0;
		 if (argumentsCount == 2)
		 {


			 params = arguments[1];

			 if (!params->IsArray())
			 {
				 exception = CefString("    2    ");
				 return true;

			 }
			 argCount = params->GetArrayLength();


		 }

		 if (argCount > 0)
		 {
			 savedstrings.reserve(argCount);
			 Params = new NetObjectToNative::tVariant[argumentsCount];
			 NetObjectToNative::tVariant* Param = Params;

			 for (size_t i = 0; i < argCount; ++i)
			 {

				 NetObjectToNative::ConvertCEFtoNet(params->GetValue(i), &Param[i], savedstrings);
			 }

		 }
		 wchar_t*  Error = nullptr;
		 NetObjectToNative::tVariant RetVal;

		 bool res = mD->pCallAsDelegate(Target, &RetVal, Params, argCount, &Error);

		 if (res)
		 {

			 retval = NetObjectToNative::ConvertNetToCef(&RetVal, true);
		 }
		 else
		 {
			 if (Error)
				 exception = CefString(std::wstring(Error));
			 delete Error;
		 }

		 if (Params) delete[] Params;

		 return true;
	 }

	 // CallNetObjectPropertySet
	 bool 	CallNetObjectPropertySet::Execute(const CefString& name,
		 CefRefPtr<CefV8Value> object,
		 const CefV8ValueList& arguments,
		 CefRefPtr<CefV8Value>& retval,
		 CefString& exception) {


		 const size_t argumentsCount = arguments.size();

		 if (argumentsCount != 3)
		 {


				 exception = CefString(L" PropertySet   3 ");
				 return true;

			}
			 
		 vector<wstring> savedstrings;


		 int Target = arguments[0]->GetIntValue();
		 wstring PropertyName = arguments[1]->GetStringValue().ToWString();
		 CefRefPtr<CefV8Value> value = arguments[2];

			 
			 savedstrings.reserve(1);
			 NetObjectToNative::tVariant Param;
			
			 NetObjectToNative::ConvertCEFtoNet(value, &Param, savedstrings);
			 


		 wchar_t*  Error = nullptr;
	
		 bool res = mD->pSetPropVal(Target, PropertyName.c_str(), &Param, &Error);

		 if (!res)
		 {
			 if (Error)
			 {
				 exception = CefString(std::wstring(Error));
				 delete Error;
			 }
			 else 
				 exception = CefString(L"   "+ PropertyName);
			
		 }

		

		 return true;
	 }

	 bool 	DeleteNetObject::Execute(const CefString& name,
		 CefRefPtr<CefV8Value> object,
		 const CefV8ValueList& arguments,
		 CefRefPtr<CefV8Value>& retval,
		 CefString& exception) {


		 const size_t argumentsCount = arguments.size();

		 if (argumentsCount != 1)
		 {
			 exception = CefString(L" DeleteObject   1 ");
			 return true;
		 }

		 CefRefPtr<CefV8Value> value = arguments[0];
		 
		 
		 mD->pDeleteObject(value->GetIntValue());

		

		 return true;
	 }

	 bool 	IteratorNext::Execute(const CefString& name,
		 CefRefPtr<CefV8Value> object,
		 const CefV8ValueList& arguments,
		 CefRefPtr<CefV8Value>& retval,
		 CefString& exception) {


		 const size_t argumentsCount = arguments.size();

		 if (argumentsCount != 1)
		 {
			 exception = CefString(L" IteratorNext   1 ");
			 return true;
		 }

		 CefRefPtr<CefV8Value> value = arguments[0];
		 wchar_t*  Error = nullptr;
		 NetObjectToNative::tVariant RetVal;

		bool res= mD->pIteratorNext(value->GetIntValue(),&RetVal, &Error);
		if (res)
		{
			retval = NetObjectToNative::ConvertNetToCef(&RetVal, true);

		}
		else
		{
			retval = CefV8Value::CreateUndefined();
			if (Error)
			{
				exception = CefString(std::wstring(Error));
				delete Error;
			}

		}
		 return true;
	 }

	 bool 	CallNetObjectPropertyGet::Execute(const CefString& name,
		 CefRefPtr<CefV8Value> object,
		 const CefV8ValueList& arguments,
		 CefRefPtr<CefV8Value>& retval,
		 CefString& exception) {


		 int Target = arguments[0]->GetIntValue();
		 wstring PropertyName = arguments[1]->GetStringValue().ToWString();

		 wchar_t*  Error = nullptr;
		 NetObjectToNative::tVariant RetVal;

		 bool res = mD->pGetPropVal(Target, PropertyName.c_str(), &RetVal,&Error);

		 if (!res)
		 {
			 if (Error)
			 {
				 exception = CefString(std::wstring(Error));
				 delete Error;
			 }
			 else
				 exception = CefString(L"    " + PropertyName);

		 }
		 else
			 retval = NetObjectToNative::ConvertNetToCef(&RetVal, true);



		 return true;
	 }

	 void SetHandlerToContex(CefRefPtr<CefV8Handler> Handler, CefRefPtr<CefV8Value> object, const char* MetodName)
	 {

		 CefRefPtr<CefV8Value> CallNetObject = CefV8Value::CreateFunction(MetodName, Handler);

		 // Add the "myfunc" function to the "window" object.
		 object->SetValue(MetodName, CallNetObject, V8_PROPERTY_ATTRIBUTE_NONE);
	 }

	 void ContextForNetHandlers::OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
	 {
		 this->context = context;
		 // Retrieve the context's window object.
		 CefRefPtr<CefV8Value> object = context->GetGlobal();
		 NetObjectToNative::ManagedDomainLoader* mD = NetObjectToNative::ManagedDomainLoader::InitManagedDomain(L"c:\\Program Files\\DNX\\runtimes\\dnx-coreclr-win-x86.1.0.0-rc1-update1\\bin\\", L"", L"");

		 //=========== CallNetMethod =======================================================
		 SetHandlerToContex(new CallNetObjectFunction(mD), object, "CallNetMethod");
		 //=========== CallNetDelegate =======================================================
		 SetHandlerToContex(new CallNetDelegate(mD), object, "CallNetDelegate");
		 //=========== PropertySet =======================================================
		 SetHandlerToContex(new CallNetObjectPropertySet(mD), object, "CallNetPropertySet");
		 //=========== PropertyGet =======================================================
		 SetHandlerToContex(new CallNetObjectPropertyGet(mD), object, "CallNetPropertyGet");
		 //=========== PropertyGet =======================================================
		 SetHandlerToContex(new DeleteNetObject(mD), object, "DeleteNetObject");
		 //=========== SetCallBacks =======================================================
		 SetHandlerToContex(new SetCallBacks(mD, this, object), object, "RegisterCallBacks");
		 //============ CallAsyncNetObjectFunction ================================
		 SetHandlerToContex(new CallAsyncNetObjectFunction(mD, this), object, "CallAsyncNetObjectFunction");
		 //============ CallNetObjectGenericFunction ================================
		 SetHandlerToContex(new CallNetObjectGenericFunction(mD), object, "CallNetObjectGenericFunction");
		 //============ IteratorNext ================================
		 SetHandlerToContex(new IteratorNext(mD), object, "IteratorNext");

	 }

	

	 
	 void ContextForNetHandlers::AsyncCalBack(const wchar_t* TaskID, bool Successfully, tVariant* ReturnValue)
	 {
		

		 if (!CefCurrentlyOn(TID_RENDERER)) {
			 // Execute on the UI thread.
			// CefPostTask(TID_UI, base::Bind(&AsyncCalBack2, TaskID, Successfully,ReturnValue, CallbackContext));
			 CefPostTask(TID_RENDERER, base::Bind(&SetCallBacks::AsyncCalBack, this->scb, TaskID, Successfully, ReturnValue));
			 return;
		 }

		 scb->AsyncCalBack(TaskID, Successfully, ReturnValue);
	 }

	 //==================== Set CallBacs
	 bool SetCallBacks::Execute(const CefString& name,
		 CefRefPtr<CefV8Value> object,
		 const CefV8ValueList& arguments,
		 CefRefPtr<CefV8Value>& retval,
		 CefString& exception) {

		    this_id = std::this_thread::get_id();
			 if (arguments.size() == 1 && arguments[0]->IsFunction()) {
				 AsyncMetodCall = arguments[0];
				 CallbackContext = CefV8Context::GetCurrentContext();
				 cfn->scb = this;

				 /*CefV8ValueList args;
				 args.push_back(CefV8Value::CreateBool(true));
				 args.push_back(CefV8Value::CreateString(L""));
				 args.push_back(CefV8Value::CreateString(L""));

				 if (AsyncMetodCall->ExecuteFunctionWithContext(CallbackContext, globalObj, args)) {
					
				 }*/
				
				 return true;
			 }
		

		 return true;

	 }

	 void SetCallBacks::AsyncCalBack(const wchar_t* TaskID, bool Successfully, tVariant* ReturnValue)
	 {
		 CefV8ValueList args;
		 
		 std::thread::id Curr_id = std::this_thread::get_id();
		 if (this_id != Curr_id)
		 {
		 }

		 if (CallbackContext.get() && CallbackContext->Enter()) {

			 args.push_back(CefV8Value::CreateBool(true));

			 args.push_back(CefV8Value::CreateString(TaskID));
			 delete[] TaskID;

			 if (ReturnValue==nullptr)
				 args.push_back(CefV8Value::CreateUndefined());
			 else
			 {
			 args.push_back(NetObjectToNative::ConvertNetToCef(ReturnValue, true));
			 delete[] ReturnValue;
			 }
 
			 
			 if (AsyncMetodCall->ExecuteFunctionWithContext(CallbackContext, globalObj, args)) {
				 
			 }
			 CallbackContext->Exit();
		 }
	 }	
}


1,.Net Core. .Net 1.

, .

. cefsimple\Release\ Test.html. cefsimple\NetObjectToNative\
CEF .Net Core. ManagedDomainLoader ClrLoader .Net Core, .

CefV8HandlersForNet JS CEF. NetConverter Net Cef.

NetObjectToCEF CEF. TestDllForCoreClr .

TestTypeScript\TestTypeScript\app\ ts Proxy. NetProxy.ts Proxy.

home.component.ts AngleSharp. counter.component.ts . TestSpeed.ts

node_modules. TestTypeScript npm install

. TestTypeScript CefProgects\cefsimple\Release\cefsimple.exe. JS. TS « « »». .

cefsimple. opensource.spotify.com/cefbuilds/index.html 32- Standard Distribution tests\cefsimple\ h NetObjectToNative.

VS 2015 CEF cmake.exe -G «Visual Studio 14»

VS 2017 cmake.exe -G «Visual Studio 15 2017».

!

Source: https://habr.com/ru/post/320960/


All Articles