Select to view content in your preferred language

E_NOINTERFACE

1089
6
02-18-2011 04:11 PM
KenSimoncic
Emerging Contributor
I have several custom extensions written in VB.net.  I compiled them into a .dll and ran proxygen against the .tlb file to generate a bunch of java proxy classes to expose the extensions outside of the ArcMap application.  I created a Java application that starts up ArcMap, waits until the AppROT says it is running, then performs the initialization that is found in all the java examples.  Then the code uses the ExtensionManager to find the extension that I created (and registered using ESRIRegasm) and calls a method I have on the extension (isRunning(boolean[])).  On my development machine (using eclipse), the code runs fine..ArcMap comes up, I call my method on the extension and it executes as expected.  Now I'm trying to deploy this to a non-development machine and it's not working.  ArcMap comes up, the license initialization code in my Java application is successfull (now...earlier posts described problems there), I find my extension calling the ExtensionManager, but now when I call isRunning, I get an Automation Exception that there is no such interface supported.  Something about the environments must be forcing my issue but I've no clue what it might be.  Can my extensions dll be anywhere I want it?  I've seen something about "well known location" for java extensions but not for a VB dll.  I guess I'm assuming the when you run ESRIRegasm that this allows the code to be able to find what its looking for.  Also, I ran acrosss a lot of information of threading apartments in trying to search for answers but I'm hoping this isn't an issue (especially since it works on my dev machine).  Any help would be greatly appreciated...running out of time to get this working.  Thanks
0 Kudos
6 Replies
RichardWatson
Deactivated User
ESRI is based on the COM machine which uses the registry to find components.  Since your extension is getting created you have much of this in place. 

Is the custom interface that you are looking for exposed to COM and in the registry?  Look for the GUID under HKLM\Interfaces.
0 Kudos
KenSimoncic
Emerging Contributor
In the registry I found the entry for the class that contains the interface that I am trying to call under HKLM\Software\Classes.  Searching for the CLSID, I find an entry in HKLM\SOFTWARE\Classes\CLSID and I can expand that but I don't see any information on the interfaces that I can call on the class.  When I registered the extension, using ESRIRegasm, I ran it on the dll and the tlb file isn't even on the deployed machine.  Is this a problem?  How does COM figure out what interfaces are valid on the class?
0 Kudos
RichardWatson
Deactivated User
The interface that you exposed to COM should have a GUID or IID.  Look for it under HKLM\Interfaces.

Compare what you see on your development machine to what you see on the production machine.

Most COM usage is based on DLLs which run inside the ArcMap process.  When you ask a COM component for an interface it simply calls QueryInterface which .NET implements for you.  The interfaces do not need to be registered for this to work.

In your case, you are calling across processes.  You have a Java application calling, via COM, a component which is running inside the ArcMap application.  In this case the interfaces must be registered because COM has to know how to marshall the arguments across processes.  This is normally done in COM by registering the type library.  My guess is that on your development machine the interface will reference a type library which you can also find in the registry.  If this is true, and it is not present on the production box, then try running regasm on the assembly on the production machine.  Probably something like "regasm myassembly.dll /tlb /codebase".
0 Kudos
KenSimoncic
Emerging Contributor
OK, thanks so far...getting closer.  When I was initially working on the extensions, I registered them on my development machine by bringing up ArcMap and choosing Customize -> Customize Mode -> Add from File and then selecting the TLB file.  This was before I had any of the COM Registration Functions in my classes so might be the reason that its working on my development maching and not a production machine.
On my development machine, the GUID for the Class which defines the interface that I want to call is in HKLM\Software\Classes\Interface.  On the production machine the GUID for the Class which defines the interface that I want to call is in HKLM\Software\Classes\CLSID (Note: There may be garbage in the registry on this machine from when the extensions were in VB6 against Arc 9.3).  So I figure my registration functions are not correct.  If I'm reading the documentation right, it looks like there are 2 places in each class that I need information.  At the top of the class I have:
<GuidAttribute("EBAF6DBE-7E4F-45F8-B56B-AD9024E5F46A"), _
      ClassInterface(ClassInterfaceType.None), _
      ProgId("AGISExtension.cAGISExtension"), _
      ComVisible(True)> _
Public Class cAGISExtension
    Implements IAGISExtension
    Implements ESRI.ArcGIS.esriSystem.IExtension


And then:
#Region "COM Registration Functions"
    ' Add the registration funcions that will be executed when ESRIRegAsm is
    ' run on the generated dll.  This will register with the ArcMap 
    ' extensions category. 
    <ComRegisterFunction(), ComVisible(False)> _
    Shared Sub RegisterFunction(ByVal registerType As Type)
        Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
        MxExtension.Register(regKey)
    End Sub

    <ComUnregisterFunction(), ComVisible(False)> _
    Shared Sub UnregisterFunction(ByVal registerType As Type)
        Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
        MxExtension.Unregister(regKey)
    End Sub

#End Region


Not sure why the ComVisible is set to false on the registration functions but that's what I found in their examples.  Does this look like all I should be doing?  (NOTE:  I did not previously have the ClassInterface, ProgID and ComVisible attributes set as part of the class declaration.)
Thanks again.
0 Kudos
KenSimoncic
Emerging Contributor
OK, after taking a reading comprehension course....
I thought there was just some sort of typo in your message because I was under the impression that I was supposed to use ESRIResgasm.  I re-read and I believe you are saying that I need to run both ESRIRegasm and regasm in my case.  That is what I did and amazingly, it worked!
Thankyou very much for getting me on the right track.
0 Kudos
RichardWatson
Deactivated User
I am glad that you sorted this out.

The way the documentation reads is that you should only have to run ESRIRegAsm.  That said, I suspect that ESRIRegAsm does not take care of the case where you are running across processes.  That is pure speculation on my part.  I think that your case is atypical.
0 Kudos