How to determine ActiveX control interface has function in client application - com

We are using a 3rd party ActiveX control in our application, recently as per our request they have added new function in ActiveX control interface and we are trying to access those function in our application. Due to some reason there are chances where we can not deploy our 3rd party ActiveX control but we are deploying our application. So old 3rd party ActiveX does not have new functions but our application which is consuming those function are trying access new function. Because of that we are getting some inconsistent behaviour lIke crash or message error box.
So we wanted to understand that is there any way to determine function of 3rd party ActiveX control exist or not in our application ? So based on that we wanted to avoid calling those function.
Thanks.

Well, you can get the type library information and try to read and walk it to determine if the function exists.
Or, you can call the function through IDispatch::Invoke and see if it fails. If it fails, don't call it again and call the fallback function.
So, it doesn't have a separate Guid for the two different interfaces? Technically, it is supposed to...but sometimes vendors don't provide new Guids for updated interfaces....I plead the 5th.
The way it is supposed to work is the you QueryInterface for the interface you want and use it.

Related

Checking for previous instance of application

I am trying to write a code to check previous instance of the application in vb.net, my requirement is that application should prevent for same user and it should allow for different user who wants to access through remote parellel 2x client..Any one please help me on this...Thanks
If you are using VB.Net, You should definetly look into WindowsFormsApplicationBase class, shipped as part of .NET framework.
There is a property (IsSingleInstance) specifically designed to provide single instance behavior to the application.
You can even receive notifications through StartupNextInstance or the counterpart OnStartupNextInstance method when another instance of the application tries to run.
I forgot to mention that My.Application already is an object of the WindowsFormsApplicationBase type (at least in VB.NET WinForms applications).
UPDATE:
Currently, to take advantage of this stuff from a VB.NET project you have to follow these steps:
Edit project properties.
Enable "Make single instance application".
Click "View Application Events".
(optionally) Implement StartupNextInstance event handler.

VSTO XML ribbon: which callback is called first

When creating a custom XML ribbon in an VSTO add-in is there an order with which the various get* callback methods are invoked (e.g. getDescription, getEnabled, getVisible, etc.)?
Surely there's an order.
But that's an internal implementation detail of Office and you absolutely shouldn't rely on that.
The only order you can rely on is the call of onLoad which is guaranteed to come first.
The rest of these methods should not rely on each other. They should be implemented as stateless as possible and should only return the requested value. (Hence their names starting with get....)
That is, you get the id of the control in and have to return some value - maybe with some information from the current Excel.Application.
One additional information:
If you need a refresh of all these get... methods, you can call IRibbonUI.Invalidate().
(You get the instance of IRibbonUI as a parameter of the onLoad call.)

How can I log [D]COM calls into a module?

Is there a way to monitor and record COM calls, with parameters, made into a specific EXE/DLL module, without explicitly adding logging functionality to the module itself? I'm thinking along the lines of how you can track windows messages in Spy++, but for COM.
The motivation is to record calls for diagnostic and automated testing purposes - e.g. click a button on a window on a client PC, monitor the COM calls sent to a server module, and later 'replay' those calls without needing the client PC.
If tools exist which do this, that is great. If not, is it something one could write and if so how?
Caller of COM method simply calls a function with agreed convention. parameters etc. and there is no middle layer between the caller and the callee, except when proxy/stub pairs are marshaling the call. Even in the latter case, there is ho standard way to hook the call for logging purposes, which you can do without specific preparations of sorts. All in all, you need to take care of tracking calls and diagnostic yourself. In can direct logging in prolog of every method of interest, or you can wrap your object/interface into customized middle layer which tracks a call and passes it further to intended callee (such as described here, for example).

.NET XML web service returned collection as array

I am working with an XML web service using VB.NET, created using VS 2010. One of my web methods returns a collection(type that inherits from list) of custom objects. It's a simple return statement, it is my understanding that .NET handles most of the tricky protocol stuff as well as serializing/unserialzing of objects.
The issue is in my consuming application when I get the the return value of the web method that returns a custom collection I get an array of the custom objects. Is this normal behavior? It will be easy enough for me to take that array and insert it into a custom collection object but if I could I would like to skip this step. Googling hasn't returned anything that I found useful. Could anyone tell me if this is typical behavior? Thanks much!
Assuming you are using WCF, try adding CollectionDataContractAttribute to your custom collection, as per Customizing Collection Types section of Collection Types in Data Contracts.
In the case you are using your service by setting up a Service Reference in the consuming application, then an even easier method would be to right-click the service name, select Configure Service Reference..., and about 1/3rd the way down of the dialog that pops up there will be a dropdown with "Collection type:" label. Default is to use System.Array, but here you can easily change it to use whichever collection type you prefer.

Simulating SideBySide for Out of Process ActiveX

We are adapting our client side relatively complicated application (ActiveX / .net / Delphi / C++ / COM ) to use SxS to achieve non admin deployment and isolation from older versions of our product.
We were able to achieve this goal for almost all our in proc components such as our .net ui, Delphi ui, and the COM servers we use in proc by composing a manifest file which described all the libraries used by our process, with no registration on the client of any of the components (almost).
And here comes the almost part:
At the moment, our application invokes (from it's c++ portion) an out of proc ActiveX server (Delphi ActiveX EXE), which in turn itself invokes another set of out of proc ActiveX servers (third party plugins, any thing goes here, Delphi, C++, any thing as long as it's out of proc ActiveX EXE and implements our interfaces).
As we know SxS does not support out of proc ActiveX servers. And we can't use these objects as in proc com servers in our main process because that would require a major rewrite of our application and even worst, a break of our public facing API which is used by third party tools and vendors, an api break which we can't allow.
We have stumbled on this article which describes how IHTMLDocument2 can be extracted from an Internet Explorer window running in a separate process. Which made us think of this approach:
We would create a secondary satellite application / process which will run the ActiveX as in process server.
Then we will use LresultFromObject and ObjectFromLresult to transfer a reference of the ActiveX object from the satellite application to the main application process. The satellite application will have it's own manifest file which will allow it to run in SxS mode.
Same approach will be taken to communicate between this Delphi ActiveX EXE and the third party AciveX EXE Plugins
There is an alternative solution, which for the moment we do not prefer over the proposed solution above which is to use .net remoting and .net com proxy classes to open the communication channel between the two processes, by translating the com request to .net remoting, and back to com on the second process.
So here comes the question:
What do you think about this approach ?
Do you see a better solution to the problem ?
It is possible to do. What is needed:
An application needs to start a server itself rather than relying on COM to do it. You don't need the extra indirection provided by the registry, just use CreateProcess().
A server should register its class factories in its main() method with CoRegisterClassObject().
Important: the CLSID it uses for each factory should be altered to be unique for each service instance. This ensures that the client connects to the correct server. I simply XOR the process ID with a class factory CLSID. The client knows the process ID as well so can make the same alteration.
The application should call CoCreateInstance() in a loop with a Sleep() call to wait for the object factory to appear. Don't declare failure until at least 60 seconds have passed (that bit me).
Both the application and the server need a manifest that contains a <file> element for each proxy/stub DLL and <comInterfaceExternProxyStub> elements for each interface that is remoted.
Alex,
nobugz is right, you can access the Running Object Table to create an instance of a COM Object from a currently running process of your Delphi automation exe.
However I have found a big issue that I cant explain. I can only access the object via the variant dispatch method when working this way.
Basically if my Active X exe is not registered, I get an "Interface Not Supported" error if I try to instance the object through interfaces for example:
WebUpdate : IAutomation;
WebUpdate := CoAutomation.Create; <-- Wont Work Error
WebUpdate : Variant;
WebUpdate := CreateOleObject('WebUpdate.Automation'); <-- Works Fine
If I register the active x exe using regserver the problem goes away!!
Go Figure!