Cannot instantiate JC4XL 1.1.3 C# APIs via Excel Addins

User 55225f2c32

07-01-2010 19:48:53

We are attempting to instantiate and use JChemExcelAPILib.IExternalAPI from within another Excel addin.


If we call the GetInstanceIds() method from within our Excel addin:


private JChemExcelAPILib.IExternalAPI _api = new JChemExcelAPILib.ExternalAPIClass();

Array ids = _api.GetInstanceIds();


The ids array contains the process id of every instance of Excel except the one running the new addin.  If only one Excel instance is running, GetInstanceIds() only returns a single "New Instance", not the process id of the running Excel.


So we attempted to obtain the process id otherwise:


Process[] procList = Process.GetProcesses();

foreach (Process p in procList)     
{

if (p.ProcessName.ToLower() == "excel")
{
activeInstance = "Excel" + ":" + p.Id.ToString();
}
}      
_api.ActiveInstance = activeInstance;


But this attempt
raises an interop service
exception, stating that the process id is not a valid one.  Specifically, we get the following exception.


{"Unable to extract JchemExcel API instances running on the desktop! (Specified instance cannot be found among running instances!)"}

Are there any suggestions on how to get a second Excel addin to communicate with the APIs provided by the JC4XL addin?



Process[]
procList = Process.GetProcesses();


 


   foreach (Process p in
procList)


        
{


           
if (p.ProcessName.ToLower() == "excel")


           
{


              
a += "Process ID=" + p.Id + "\t" + "Process
Name="
+ p.ProcessName + "\n";


              
activeInstance = "Excel" + ":" + p.Id.ToString();


           
}


        
}


 


        
_api.ActiveInstance = activeInstance;


ChemAxon bd13b5bd77

07-01-2010 21:02:19

Dear Brett!

Please download the documentation of JChem4XL API from our http://www.chemaxon.com/download.php?d=/data/download/jchem4xl/JChem_for_Excel_API_Guide_1.1.3.zip />download website.


In API guide information can be found about internal and external API.



If you write addin and would like to use the 'sibling' addin (JChem4XL itself) please try to use internal API instead. In the documentation it was tried to be highlighted that internal and external API both are based on the IJChemExcelAPI interface. Internal API is designed to access the Jchem4XL instance inside the Excel instance where your Addin or VBA module is running.
External API is mainly targeting to create a "New Instance" or attach external instances.



 Please check the VBA example:



   ' Excel addin is the list of Excel specific automation addins
   ' COM Addins are the real Office plugins loaded in at startup
   Set objAddin = Application.COMAddIns("JChemExcel.JChemExcelAddin")
   Set jeJchemForExcel = objAddin.Object



where jeJchemForExcel is:



   Dim jeJchemForExcel As JChemExcelCOMInterfacesLib.IJChemExcelAPI




from C# you the JChemExcelCOMInterfacesLib COM component should be added.



Please do not use custom code based on observation how Jchem4XL identifies a running instance (process id and "Excel:").


This can be changed build by build, only the API needs to be used since it can only be reliable and consistent, compatible with your code. So what the GetInstanceIds returns one of them needs to be set as active one regardless of what is its content. Just for those cases if you would like to access Jchem4XL running instances from a stand alone application.






If you have further questions, comments re API please do not hesitate to contact us. 


Best regards,
Viktor


 














User 55225f2c32

08-01-2010 22:03:17

We translated your VBA sample into C# code we hoped would be accessible from "OurNewAddin".



using JChemExcelCOMInterfacesLib;
using Microsoft.Office.Interop.Excel;
using Application=Microsoft.Office.Interop.Excel.Application;
...
Application
app = Globals.OurNewAddin.Application;
//Also tried: Application app = Globals.OurNewAddin.Application.Parent;

string
appName = app.Name; // appName is equal to “Microsoft Excel”


var
addins = app.COMAddIns; 

object
jChemAddinStringObject = "JChemExcel.JChemExcelAddin"; 

COMAddIn
objAddin = addins.Item(ref jChemAddinStringObject); 

//Also tried: object objAddin =
addins.Item(ref  ChemAddinStringObject).Object; 


IJChemExcelAPI
jeJchemForExcel = (IJChemExcelAPI)objAddin.Object;


string[] structures = { "C1=CC=CC=C1","C1=CC2=C(C=C1)C=CC=C2" };

Workbook
workbook = (Workbook)Globals.OurNewAddin.Application.ActiveWorkbook;
Worksheet worksheet = (Worksheet)Globals.OurNewAddin.Application.ActiveSheet; 

jeJchemForExcel.AddStructuresToColumn(structures, "smiles", 1,"Demo header", workbook.Name, worksheet.Name, 1);
 

But this attempt failed with a method access exception upon executing AddStructuresToColumn






System.MethodAccessException: Attempt to access the method failed.   
at JChemExcelCOMInterfacesLib.IJChemExcelAPI.AddStructuresToColumn(Array
structures, String Format, Int32 column, Object header, Object workbookName,
Object worksheetName, Object startRow)



However, we do notice that the code above works after we "manually start" JC4XL by clicking any of the JChem ribbon items


JChem seems to then load (and display its splash screen), making it available for use from other plugins.  This brings us tantalizingly close to our goal.


Do you have any ideas on how we might trigger JC4XL to load into memory without clicking the ribbon buttons?


Thanks in advance,


Brett




Application app
= Globals.HeliumAddIn.Application;


//app =
Globals.HeliumAddIn.Application.Parent;    I also tried with
this instruction


 


string
appName = app.Name; // appName is equal to
“Microsoft Excel”


 


var addins
= app.COMAddIns;


object
jChemAddinStringObject = "JChemExcel.JChemExcelAddin";


COMAddIn objAddin
= addins.Item(ref jChemAddinStringObject);


 


IJChemExcelAPI
jeJchemForExcel = (IJChemExcelAPI)objAddin.Object;


 


string[] structures = { "C1=CC=CC=C1",
"C1=CC2=C(C=C1)C=CC=C2" };


Workbook
workbook = (Workbook)Globals.HeliumAddIn.Application.ActiveWorkbook;


 


try


        
{


           
jeJchemForExcel.AddStructuresToColumn(structures, "smiles",
1,


                                              
"Demo header", workbookName,


                                              
worksheetName, 1);


        
}


        
catch (Exception
exc)


        
{


           
string exceptionMsg = exc.Message;


        
}


User 68dcd1c0ae

11-01-2010 09:55:41

Hi Viktor, I'm Federico and I work with Brett.


I can't launch the VB6 application you gave me.


But I found the root of the problem. It's the initialization.


In fact if I launch a JChem function (from the ribbon) and after doing that I try to execute the method Brett posted previously, it does work.


While it does not work if I launch the method directly without manually calling a JChem function before. So I guess that some initialization I'm not aware of is made by JChem behind the scene when I directly use it from Excel.


Do you have an example (in C# or in VB.net ) of the initialization of all the instances needed to launch the "AddStructuresToColumn" method?

ChemAxon bd13b5bd77

11-01-2010 10:11:36

Hi Federico,


yes, you can find error logged under YourUser\AppData\Roaming\ChemAxon\JChem for Excel on Vista and Documents&Setting\Applciation Data\Chemaxon\ JChem for Excel


if any error occurs you find the problems in


JCHEMforEXCEL_date.jxllog.


I suggested two different examples to you, 1 of them is the VBAMacro, which works similarly to a COM addin and the other one is the test COM Addin, please check them both.


Yes you can find C# code in


http://www.chemaxon.com/download.php?d=/data/download/jchem4xl/JChem_for_Excel_API_Guide_1.1.3.zip


running (initializing Jchem) from a standalon application and VBA code to initialize Jchem from inside Excel. Both should be working.


The problem is only from VSTO (Visual Studio Tools for Office) I think since .NET security issues might be causing the issue.http://blogs.msdn.com/andreww/archive/2005/10/04/interaction-between-loaded-add-ins.aspx


http://msdn.microsoft.com/en-us/library/aa159894(office.11).aspx
Above I recommended COMShim for you to load the managed part if you would like to use the code from Addin.


Viktor