Book a Demo

Author Topic: Calling an AddIn from the native EA Script Engine  (Read 10928 times)

EXploringEA

  • EA User
  • **
  • Posts: 172
  • Karma: +8/-0
    • View Profile
Calling an AddIn from the native EA Script Engine
« on: February 12, 2015, 04:14:47 am »
Hello,

Don't ask the reason but its to do with purely exploring EA, so probably not a real use case, just fun.  I can't seem to find a mechanism for a script running within the native EA scriptcontrol (not one under our program control) to make a call to a running addin, in which we have written known public callable methods.

I guess the question really comes down to - can I find a reference to the current instance of AddIn's class library that is being used by EA, and then it should be possible.  I've tried various windows process inspections but not gone too far.  I guess with perseverance I can look for processes whose parents and EA, and try to find the correct instance, but so far not found the correct object.

I haven't seen anything on the forum but wondered if anybody had done this or had a slick solution, otherwise I'll go back to diving in to the engine room of windows :(

Thanks

Adrian
EXploringEA - information, utilities and addins

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +397/-301
  • I'm no guru at all
    • View Profile
Re: Calling an AddIn from the native EA Script Eng
« Reply #1 on: February 12, 2015, 04:54:14 am »
Check Geert's addin-extension. That will do what you want.

q.

EXploringEA

  • EA User
  • **
  • Posts: 172
  • Karma: +8/-0
    • View Profile
Re: Calling an AddIn from the native EA Script Eng
« Reply #2 on: February 12, 2015, 09:45:36 am »
Thanks but as far as I can see I am not sure it will.  Geerts AddIn, which I have yet to review, looks like it captures events and runs scripts in response to those events, but what I am looking for is the hooks to call the AddIn from a script.  I.e. The other way round.   Would be pleased to know that it is included in the AddIn and if so I must try it.

I can see that although EA must have a reference to each AddIn that is loaded and it is not exposed and really there is no real use case for them to provide through the API.  I am curious as to whether it can be done - it is an unusual requirement however it does mean that a script could access the current instance of the AddIn functionality.  Of course, it is possible to get details of the AddIn class and run another instance but that defeats the object of the exercise. It is having access to the current instance that's important.

As I said I can probably find by going through windows processes but this seems like a hammer to crack a nut ;D

EXploringEA - information, utilities and addins

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13506
  • Karma: +572/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Calling an AddIn from the native EA Script Eng
« Reply #3 on: February 12, 2015, 06:25:41 pm »
In most of the examples I published I actually do that. I'm using the public methods from my Enterprise Architect Add-in Framework in my scripts.

For instance in Prevent accidental deletes with EA-Matic
Quote
Usage of Enterprise Architect Add-in Framework

This script also illustrates how you can use the Enterprise Architect Add-in Framework within your script.

This extensive open source framework is the basis for the add-ins EA-Matic and EA Navigator, and offers a much more functional interface to the model then the standard EA API.

This code inializes the model object with the current Repository

Code: [Select]
set model = CreateObject("TSF.UmlToolingFramework.Wrappers.EA.Model")
model.initialize(Repository)
It is then further used to get the element based on the ElementID from the Info object

Code: [Select]
set element = model.getElementWrapperByID(elementID)The element then gives us access the attributes and parameters using this element by means of
Code: [Select]
set usingAttributes =  model.toArrayList(element.getUsingAttributes())
set usingParameters = model.toArrayList(element.getUsingParameters())

You just have to make sure that the classes are COM visible, and that your dll is COM registered (which in case of your add-in dll is already the case).
Then the tricky part is that some objects are not known in the COM scripting environment.

That is the reason why I added toArrayList and toObject to the Model.cs class.
toArrayList converts an type of collection (such as List<T>) to an ArrayList that can be used by the script. Generic collection cannot be used in a COM environment.
toObject does a very stupid thing. It returns the an object as an Object. You need that if a method or property returns an interface. COM doesn't known how to deal with that (unless you do very specific things in the code)

As for the "current instance" issue. If you pass it to the scripting environment first as a parameter then you should be able to use it without having to create a new instance.

Geert
« Last Edit: February 12, 2015, 06:28:34 pm by Geert.Bellekens »

EXploringEA

  • EA User
  • **
  • Posts: 172
  • Karma: +8/-0
    • View Profile
Re: Calling an AddIn from the native EA Script Eng
« Reply #4 on: February 12, 2015, 07:36:51 pm »
Hi Geert


Thanks for the explanation of what you are doing.  You describe the use case of the script CREATING a new object that it wants to use, that's fine, however the DLL is will be a new instance.

And as you say "As for the "current instance" issue. If you pass it to the scripting environment first as a parameter then you should be able to use it without having to create a new instance."

That is exactly what I want to do however the issue is finding the current instance, which in my case is the DLL for a currently running AddIn.

So what I am looking at is the case when I am using an EA Script running in the normal EA environment connecting to an EXISTING instance of a DLL, explicitly I'm wanting to use the current instance of a running AddIn. Is there anywhere apart from within the windows process list that could provide a reference to the DLL.  Clearly EA has a copy internally but I don't see that exposed (nor would expect it to expose it).

So I have an active AddIn running, and in writing it I have exposed public methods that are not related to the standard EA AddIn interface but are exposed,  with the idea that a user could create and run scripts which can go and access these methods within the context of the current environment and with the current state of the addin.

I have worked out a potential solution that involves creating a new object (DLL) which will need to be called to get the reference, by working through windows processes to find the correct DLL and provide a reference back to the calling script which can then be used as a handle to allow the script to call one of the exposed methods in the AddIn.  Not tested this yet,  but I was thinking there must be a more elegant way.

Have I missed something?

Unusual yes - but I think there are some interesting uses.

Adrian
« Last Edit: February 12, 2015, 07:38:12 pm by MrWappy »
EXploringEA - information, utilities and addins

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13506
  • Karma: +572/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Calling an AddIn from the native EA Script Eng
« Reply #5 on: February 12, 2015, 07:52:40 pm »
Adrian,

Are we talking about an add-in that you write yourself?
In that case, shouldn't it be possible to store an instance of the add-in in a static attribute?
If you return that static attribute from a "normal" operation then it might return this same instance to the script environment.

I hope since both the script and the add-in run in the EA application environment that they share the static elements.

If that doesn't work then there surely must be a way to connect somehow to the running instance, but I wouldn't know right now how to do that.

Geert

EXploringEA

  • EA User
  • **
  • Posts: 172
  • Karma: +8/-0
    • View Profile
Re: Calling an AddIn from the native EA Script Eng
« Reply #6 on: February 13, 2015, 01:21:58 am »
Hi Geert


Yes the idea is to allow a script to access an AddIn I've written.

I think you idea is elegant and just what I was looking for - a second pair of eyes to look at the issue differently.  I thought this was going to be the answer.

However on testing with my addin called "ScriptTester" and storing an instance of "myself" in attribute "AddInInstance"  the script which includes the lines

a = AddInInstance

a = ScriptTester.AddInInstance

etc.


I get the errors Objectrequired:'ScriptTester'  so my guess is that EA doesn't refer to my addin via the class name.  I tried a few variants and each produced similar errors.

Is this what you had in mind - or have I missed the point.

Still exploring and hopefully find something otherwise back to windows stuff.

BR

Adrian

EXploringEA - information, utilities and addins

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13506
  • Karma: +572/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Calling an AddIn from the native EA Script Eng
« Reply #7 on: February 13, 2015, 01:37:48 am »
Adrian,

I was thinking more something like

(freehand code)
Code: [Select]
public class MyAddin
{
   private static MyAddin myAddinInstance {get;set;}
   public void EA_OnPostInitialized(EA.Repository repository)
  {
       MyAddin.myAddinInstance = this;
  }
   public MyAddin getInstance()
  {
      return MyAddin.myAddinInstance:
   }
}
Then in the script do something like
Code: [Select]
dim myAddin
Set MyAddin = CreateObject("MyNameSpace.MyAddin")
dim myAddinInstance
set myAddinInstance = MyAddin.getInstance()

But I'm not sure if that is going to work. I don't know enough about application environments and stuff like that.

Geert

EXploringEA

  • EA User
  • **
  • Posts: 172
  • Karma: +8/-0
    • View Profile
Re: Calling an AddIn from the native EA Script Eng
« Reply #8 on: February 13, 2015, 04:07:57 am »
Hi Geert

Thanks for the suggestions which I've now had time to try.
And I guess my suspicions that the Script control use of a DLL is separate from the AddIn version of the dll is try.

I made the additions you suggestions to my addin (ScriptTester) and then ran the script creating an object and guess .. yes there are now 2 instances of the DLL with different load addresses - if you click to see an image of the output from the  process explorer http://bit.ly/1zaNmgM you can see the detail.

I haven't given up on your idea as I think it sort of makes sense it is just how to find a place where an object can be stored and accessible to all!  Mind you I don't like working at the process levels - did enough of that years ago when I used to write operating systems software (pre windows XP !!)

I'll keep you updated - and as you will see from my ongoing blogs on scripting (next one monday 16th) - I'm working through potential scenarios for automating using scripts.  Hopefully I can solve this - its blog post is already schedule for the week after next.

Thanks and BR

Adrian

PS: Anyone else have ideas??
EXploringEA - information, utilities and addins

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13506
  • Karma: +572/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Calling an AddIn from the native EA Script Eng
« Reply #9 on: February 13, 2015, 04:36:45 am »
Hmm too bad that didn't work. I'll think about it further. Maybe I'll come up with an idea later.

Geert

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13506
  • Karma: +572/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Calling an AddIn from the native EA Script Eng
« Reply #10 on: February 13, 2015, 04:45:43 am »
I'm a bit intrigued now, and I was googling for a possible solution.
Check-out http://stackoverflow.com/questions/18731298/how-to-make-multiple-dll-instances-able-to-access-each-other
According to one answer there should only be one instance of a dll in a single process so in theory it should be possible to access the static variables.

Geert


EXploringEA

  • EA User
  • **
  • Posts: 172
  • Karma: +8/-0
    • View Profile
Re: Calling an AddIn from the native EA Script Eng
« Reply #11 on: February 13, 2015, 05:15:57 am »
Geert

Thanks - I'm sure there is a solution what worries me at the moment is that having seen that EA has 2 instances of the DLL, even my long winded search through process to find the DLL would be thwarted as there are 2 so which do I chose.

I plan to explore this further.

I'll check out the stackoverflow reference - we have already seen 2 instances in a single process.  Interesting I also noticed that some other AddIns were loaded twice - plus there are multiple copies of the InterOP dll - so what's going on?  Does every AddIn get an instance of the DLL - I suspect it could.

Well I'll keep on exploring as is my mission ;)
EXploringEA - information, utilities and addins

EXploringEA

  • EA User
  • **
  • Posts: 172
  • Karma: +8/-0
    • View Profile
Re: Calling an AddIn from the native EA Script Eng
« Reply #12 on: February 13, 2015, 05:40:21 am »
Forgot to add a link to an image that illustrates some of the other libraries that are loaded multiple times. http:// http://bit.ly/1Asfb8L


From the Process Explorer help:

When you select the Relocated DLLs entry in the Options|Configure Highlighting dialog any DLLs that are not loaded at their programmed base address show in purple.

DLLs that cannot load at their base address because other files are already mapped there are relocated by the loader, which consumes CPU and makes parts of the DLL that are modified as part of the relocation un-sharable. "

EXploringEA - information, utilities and addins