Getting a specific instance of COM object in VB.Net -


i writing windows form application in .net list running instances of third-party cad/cam software (in case catia) , let user choose 1 of them perform couple of automated tasks. performing automated tasks, need specific instance of com objects - compared getobject() gives me non-specific com instance. there way specific com instance using window handle or other methods?

update: raymond said there no single solution com objects; managed catia com objects using following code (which uses rot fill list catia com instances name):

<dllimport("user32.dll", charset:=charset.auto)> private shared sub getclassname(byval hwnd system.intptr, byval lpclassname system.text.stringbuilder, byval nmaxcount integer) end sub <dllimport("ole32.dll", exactspelling:=true, preservesig:=false)> private shared function getrunningobjecttable(byval reserved int32) irunningobjecttable end function <dllimport("ole32.dll", charset:=charset.unicode, exactspelling:=true,  preservesig:=false)> private shared function createitemmoniker(byval lpszdelim string, byval lpszitem string) imoniker end function <dllimport("ole32.dll", exactspelling:=true, preservesig:=false)> private shared function createbindctx(byval reserved integer) ibindctx end function  try      dim rotobject object = nothing     dim runningobjecttable irunningobjecttable     dim monikerenumerator ienummoniker = nothing     dim monikers(1) imoniker      runningobjecttable = getrunningobjecttable(0)     runningobjecttable.enumrunning(monikerenumerator)     monikerenumerator.reset()      dim numfetched intptr = new intptr()     while (monikerenumerator.next(1, monikers, numfetched) = 0)         dim ctx ibindctx         ctx = createbindctx(0)          dim runningobjectname string = ""         monikers(0).getdisplayname(ctx, nothing, runningobjectname)          runningobjectname = runningobjectname.toupper         if (not runningobjectname.equals(""))             dim runningobjectins object = nothing             runningobjecttable.getobject(monikers(0), runningobjectins)              'check if object catia object             try                 dim catiains infitf.application = nothing                 catiains = directcast(runningobjectins, infitf.application)                 listcatia.items.add(catiains.windows.count)              catch exc exception                 messagebox.show(exc.tostring())             end try         end if     end while  catch exc exception     throw exc end try 

however, catia instances refer first catia application loaded. no idea why, anybody?

the "problem" in code calling getobject always returns first active server finds in running object table (rot). enumerating rot doesn't change behavior , little frustrating because show there more 1 server in rot. note of items returned in enumeration may not running: getobject returns first active server -- not first 1 returned enumeration.

however, in case of catia in particular is possible specific instance. suspect possible many applications if can particular instance of interest run code, on demand, before pointer com instance.

for catia, rough outline of process use:

 1. make dll 2 functions:     hresult __stdcall comarshaltofile(iunknown* punk, const char* const filepath)     /* uses `::createstreamonhglobal`, `::comarshalinterface`, `::cogetmarshalsizemax`,      , `::gethglobalfromstream` marshal iunknown specified file.     */     hresult __stdcall comarshalfromfile(iunknown** ppunk, const char* const filepath)     /* uses `::createstreamonhglobal` , `::counmarshalinterface` marshal      file iunknown pointer.     */  2. in catia:   note: needs done on development computer.   make new "vba projects" macro library.      add "declare" statements for:         "loadlibrary" (windows api)         "comarshaltofile" (dll specified above)     add function          public function marshalcatiatofile _             (marshalinstancefilepath string, _                 marshaldllfolder string) long      marshalcatiatofile calls "loadlibrary" load c++ dll     , calls comarshaltofile (in dll) marshal catia instance     file.    remove macro library catia's list of macro libraries.  3. create file:     "c:\temp\catiaontheflycatscripts\ontheflycatscript.catvbs"   file can empty.  4. in catia:       note: must done *each* user of catia on *each* computer used.       may possible make available users without individual       setup required: saved in "frameuseraliases.catsettings"       may possible reverse engineer settings file , set       needed data outside catia.      add "c:\temp\catiaontheflycatscripts\" new "directories" macro library.     make added library "current"     use "tools --> customize --> commands --> macros" assign       "user alias:" "ontheflycatscript.catvbs" script file.       name alias "executeontheflycatscript".     remove macro library catia's list of macro libraries.     close catia @ point force changes saved.  5. vb.net / c# program:       add dll (from step 1) , catvba macro library (from step 2)       "embedded resource" project.         during program execution:         extract dll , macro library appropriate location.          load dll session using "loadlibrary".         create file:           "c:\temp\catiaontheflycatscripts\ontheflycatscript.catvbs"          "ontheflycatscript.catvbs" executed in catia.           uses catia.systemservice.executescript execute            "marshalcatiatofile" function in catvba macro library.           add method of choice file indicate success/failure.           use dialog box appropriate title.          execute "ontheflycatscript.catvbs":           using windows api functions, window handle             "power input" box @ bottom right of "desired"              catia window.           using windows api functions (*not* "sendkeys") send              "c:executeontheflycatscript" + {enter} "power input".           wait "completion" signal script. if used             dialog box, use windows api function close it.          assuming script succeeded in marshaling catia instance           file, call dll function comarshalfromfile catia           instance.  

it's lot of work many "moving" parts allow automate multiple catia sessions "simultaneously". works purposes: automated extraction of data set of catia models , automated creation of set of catia models using more 1 catia session @ time. bottleneck application individual catia session -- not cpu resources (using dual processor 4 or 6 core per processor machine); adding more sessions improves throughput.


Comments