Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetObject with edge.js

I'm currently working to replace my ActiveX-Implementation in IE through a REST-API based on node.js with running edge.js

So far the basic examples from the page implementing worked pretty well. I have my index.js set up to

var edge = require('edge');
var edgeVb = require('edge-vb');
var path = require('path');

var helloVb = edge.func('vb', path.join(__dirname, 'simpleVbFunction.vb'));

helloVb('Testing with String', (err, res) => {
    if(err) throw err;
    console.log(res);
});

And the simpleVbFunction.vb as

Async Function(Input As Object) As Task(Of Object)
    Return Await Task.Run(Function()
        Return "NodeJS Welcomes: " & Input.ToString()
    End Function)
End Function

So far so good. Now i want to be able to access an application running on the machine running node.js. In this case Catia (could as well be Excel though)

Usually for this I'd use a simpleVbFunction.vb like this

Async Function(Input As Object) As Task(Of Object)
    Return Await Task.Run(Function()
        Dim CATIA as Object
        set CATIA = GetObject(, "CATIA.Application")
        Return CATIA.ActiveDocument.Application.FullName
    End Function)
End Function

However this does not work. I'm getting the following error.

Error: Unable to compile VB code. ----> Errors when compiling as a CLR library: C:\Users\xxxxxx\AppData\Local\Temp\4hf2uw3z.0.vb(1,0) : error BC30203: Bezeichner erwartet. ----> Errors when compiling as a CLR async lambda expression: C:\Users\xxxxxx\AppData\Local\Temp\cypj4ltp.0.vb(7,0) : error BC30451: "GetObject" ist nicht deklariert. Auf das Objekt kann aufgrund der Schutzstufe möglicherweise nicht zugegriffen werden. at Error (native) at Object.exports.func (C:\Users\xxxxxx\coding\node\tst_win32ole\node_modules\edge\lib\edge.js:169:17) at Object. (C:\Users\xxxxxx\coding\node\tst_win32ole\index.js:6:20) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Timeout.Module.runMain [as _onTimeout] (module.js:604:10) at ontimeout (timers.js:386:14)

Now I have to admin my VB.NET skills are a little bit rusty and this might just be an error in my VB-Code but I think it's something else. Has anyone of you been able to access a COM-Object via edge.js and if yes how was this possible?

[edit] OK. I came a little further by switching to C# from VB (At least the code commented out to access the name of the Excel Application works). But this opened another problem. My code here looks like this

using System.Threading.Tasks;
using System;
using System.Runtime.InteropServices;
// using INFITF;

   public class Startup
   {
       public async Task<object> Invoke(object input)
       {
            // dynamic xl = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
            // return xl.Name;
           object CATIA0 = Marshal.GetActiveObject("CATIA.Application");
           INFITF.Application CATIA = CATIA0 as INFITF.Application;
       }
   }    

Now the problem is, that when working with Visual Studio and compiling the dlls get included automatically (when setting CATIA as INFITF.Application). But with edge.js I'd get the error that the namespace INFITF could not be found. Any ideas how to get that working?

Sorry for the long question. I'll tidy this up after this is solved.

[/edit]

like image 862
relief.melone Avatar asked Nov 10 '17 12:11

relief.melone


1 Answers

OK. I figured out most of it. First as you are not working with an IDE and you won't add Ressources like you're used to be this will work different with edge.js. You will have to find your dll and implement it. In my case I had to find the

Interop.INFITF.dll

from the Catia directory.

After that your node.js Code will look like this. (My functionality for testing now was just that once a second I'll log the name of the currently opened Part in Catia)

var edge = require('edge');
var path = require('path');

var getCat = edge.func({
    source: path.join(__dirname, 'accessCatia.cs')
, references :[
    './Resources/Interop.INFITF.dll'   
]});

setInterval(function(){
    getCat('someInputString', (err, res)=>{
        if(err){
            console.log('ERROR FOUND: ');
            console.log(err);
            return;
        }
        console.log(res);
    });
},1000);

My accessCatia.cs will look like this.

using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System;


   public class Startup
   {
       public async Task<object> Invoke(object input)
       {

           object cat0 = Marshal.GetActiveObject("Catia.Application");
           INFITF.Application cat = cat0 as INFITF.Application;
           INFITF.Document doc = cat.ActiveDocument as INFITF.Document;

           return doc.FullName;

       }
   }

Now what's still open is that the objects recieved seem to have a different structure than what you'd get with VB.net or via ActiveX in the Internet Explorer. For example

doc.FullName exists as regular but doc.Name will not be found when using C# instead you'd have to use doc.get_Name().

Unfortunately DassaultSystems is pretty bad in terms of documentation but that might be stuff for another topic.

like image 131
relief.melone Avatar answered Nov 18 '22 12:11

relief.melone