GetObject с помощью edge.js
В настоящее время я работаю над заменой моей ActiveX-реализации в IE через REST-API на основе node.js с запущенным edge.js
До сих пор основные примеры из реализации страницы работали довольно хорошо. У меня есть index.js, настроенный на
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);
});
И простой VbFunction.vb как
Async Function(Input As Object) As Task(Of Object)
Return Await Task.Run(Function()
Return "NodeJS Welcomes: " & Input.ToString()
End Function)
End Function
Все идет нормально. Теперь я хочу получить доступ к приложению, запущенному на компьютере, на котором выполняется node.js. В этом случае Catia (хотя может быть и Excel)
Обычно для этого я бы использовал simpleVbFunction.vb, как это
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
Однако это не работает. Я получаю следующую ошибку.
Ошибка: невозможно скомпилировать код VB. ----> Ошибки при компиляции в виде библиотеки CLR: C:\Users\xxxxxx\AppData\Local\Temp\4hf2uw3z.0.vb(1,0): ошибка BC30203: ошибка Bezeichner. ----> Ошибки при компиляции в виде асинхронного лямбда-выражения CLR: C:\Users\xxxxxx\AppData\Local\Temp\cypj4ltp.0.vb(7,0): ошибка BC30451: "GetObject" не является декларацией. Auf das Objekt kann aufgrund der Schutzstufe möglicherweise nicht zugegriffen werden. при ошибке (родной) в Object.exports.func (C:\Users\xxxxxx\coding\node\tst_win32ole\node_modules\edge\lib\edge.js:169:17) в Object. (C:\Users\xxxxxx\coding\node\tst_win32ole\index.js:6:20) в Module._compile (module.js:570:32) в Object.Module._extensions..js (module.js:579:10) в Module.load (module.js:487:32) в tryModuleLoad (module.js:446:12) в Function.Module._load (module.js:438:3) в Timeout.Module.runMain [as _onTimeout] (module.js:604:10) в ontimeout (timers.js:386:14)
Теперь я должен сказать, что мои навыки работы с VB.NET немного устарели, и это может быть просто ошибкой в моем VB-коде, но я думаю, что это нечто другое. Кто-нибудь из вас имел доступ к COM-объекту через edge.js, и если да, то как это было возможно?
[править] ОК. Я пошел немного дальше, переключившись на C# из VB (по крайней мере, закомментированный код для доступа к названию работы приложения Excel). Но это открыло еще одну проблему. Мой код здесь выглядит так
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;
}
}
Теперь проблема в том, что при работе с Visual Studio и компиляции dll включаются автоматически (при установке CATIA как INFITF.Application). Но с edge.js я получил бы ошибку, что не удалось найти пространство имен INFITF. Есть идеи, как заставить это работать?
Извините за длинный вопрос. Я уберу это после того, как это решится.
[/редактировать]
1 ответ
ХОРОШО. Я понял большую часть этого. Во-первых, поскольку вы не работаете с IDE и не добавляете Ressources, как вы привыкли, это будет работать с edge.js. Вам нужно будет найти свою dll и реализовать ее. В моем случае я должен был найти
Interop.INFITF.dll
из каталога Catia.
После этого ваш код node.js будет выглядеть следующим образом. (Моя функциональность для тестирования теперь заключалась в том, что раз в секунду я буду записывать имя открытой в данный момент части в 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);
Мой accessCatia.cs будет выглядеть так.
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;
}
}
Теперь все еще открыто то, что полученные объекты, похоже, имеют структуру, отличную от той, которую вы получили бы с VB.net или через ActiveX в Internet Explorer. Например
doc.FullName существует как обычный, но doc.Name не будет найдено при использовании C#, вместо этого вам придется использовать doc.get_Name().
К сожалению, DassaultSystems довольно плохо с точки зрения документации, но это может быть материал для другой темы.