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

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).

Related

What do you call the process that makes use of an API?

At my work the term API is thrown around loosely.
It's often used to describe automated processes composed of batch files, scripts, SQL stored procedures, SQL jobs, Windows tasks, etc.
It confuses my boss and management when I try to talk about an actual API, the interface (i.e., a vendor's protocol for what endpoints to use, how to pass keys, call limits, access token use, expected JSON structure, where to pass particular parameters, how errors should be interpreted, etc.) I tried to explain that this is the more literal definition, and refer to the piece I'd develop as the process that interacts with the API. I feel like I'm only confusing them more though.
Is there a term for the process one develops to interact with an API to automate things? If there's no specific term, how do you refer to it?
At my current position, we tend to call this process “integration”. We are integrating the external or internal API with another backend process or with a front end client application.

Can you use third party .dlls in SAPUI5?

I am redesigning a Reman service, which currently exists as a thick client application that receives SAP Optimization Jobs (from SAP), calculates the best way to optimize product use (Optimizer) and display the best optimization on the client. They can either edit or submit the optimization back to SAP
I am trying to create a SAPUI5 application that either:
Reaches out to an external web server to run a small application (Optimizer) and returns the data back to the UI5 application.
or
Load the third party dll into SAP UI5 and call the Optimizer that way.
Is this possible? Can you use third party dlls in UI5?
SAPUI5 - as the name says - is a UI framework. From your description, I understand that you're trying to pull business/processing logic into the UI. This is usually considered a bad idea. You should rather put the business logic (i. e. your optimizer) into a server-side component (anything that would ideally provide OData services) and use UI5 to create a front-end for that.
It appears that in both solutions you proposed, the business logic is on the server, which is a good practice.
Although it isn't impossible to call a DLL from Javascript, it isn't a very good idea, because there is no possibility to make this browser-independent. There may even be incompatibilities between various versions of the same browser when calling DLLs.
It would by far be the preferred way to call the optimizer webservice from the UI5 application. In fact, UI5 is completely designed to facilitate calling web-services and provides various components that will help you to make the actual call and bind the returned data to user-interface controls.
it is possible as long you have the dll registered in the machine which is running the UI5 Application and you're using JScript for such.

How should one write an XPC service with state?

I've read the NSXPC* docs, which advise making the vended service as stateless as possible. It's a good idea, at least to the docs and examples I've read, since the service and the calling app see each other as singletons and only one instance of the service runs at a time. This means that the methods are essentially non-member functions (to use a C++ term).
Why do I want to get around this? I want to put the network code into a XPC. Since the XPC will be working with a GUI app, which will have multiple windows, I need to support multiple simultaneous connections. That doesn't work with singletons, at least directly.
The network API is C-based, with the main state type a pointer to a custom struct. So why don't we do something similar:
Have the creation function return a value type, like NSUUID or something. (Passing a pointer across processes would be a bad idea.)
In the service, create a NSDictionary (or std::map or whatever) mapping between the NSUUID and the API C-pointer.
The various service APIs take the UUID and convert it to the C-pointer to use the network API.
Aside: Since the token is random, if the XPC service crashes, the main app will have a token that's useless after the XPC is restarted. Maybe I should a URL (which would have all the information to restart) instead. But then we get potential conflicts if two connections happen to be to the same server. Maybe I can combine the ideas with the token being a URL/UUID pair. (The UUID value would move from being returned by the service to supplied by the main app.)
Would this be a good way to implement state-full XPCs?
You may want to add a method to your service interface which replies with a long-lived proxy object. You can arrange for this to happen by means of a call to -[NSXPCInterface setInterface:forSelector:argumentIndex:ofReply:], passing YES for the last parameter. Details are available here:
https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSXPCInterface_reference/#//apple_ref/occ/instm/NSXPCInterface/setInterface:forSelector:argumentIndex:ofReply:

COM in a Windows form EXE using Visual Basic/Visual Studio 12

I don't usually program in the .NET framework however I've needed to use it to create a simple exe application that logs data from some measurement equipment. I want this application to have an automation interface with a couple of methods. I've done this before using Delphi/Pascal and it was very straightforward, and I can create a Class Library in Visual Studio that registers itself and the methods and can easily be interfaced with but adding a ComClass to the windows form application doesn't work, can anyone point me in the right direction?
This started as a comment but just kept growing, hopefully i am not off track ...
You can only register a dll. So the short answer would be to add a class library to your project and put the com class in there. This would allow you to share the functionality of the class, but not the same instance of that class.
I think your problem is that you are trying to establish Interprocess Communications. My immediate suggestion is not to do that, at least at first.
For a start you could have your com app interface with a .net class library which would log data. You could then have another project with a .net executable that displays the log, and updates periodically. Now you have .net code on both sides of the fence and can start investigating ways to get them to talk to each other.
The hard part is invoking methods and returning values. If you really need a responsive system you can investigate named pipes inter-process communication, or using a WCF service with callbacks between the two systems. The problem is that in either case you are hamstrung by the class library not being hosted by .net so you have limited functionality (no config file etc). If you can put up with a time lag I would suggest simply starting with writing messages to a local datastore and then polling from each client, every 30 seconds or so. For example the app would create a message saying "give me measurement A" and then start polling every second. The DLL would have a timer and within 30 seconds would read that message and write its own message with the measurement, which the EXE would read and then display. Once you get that system up and running you can decide whether you need to tackle inter-process communication, which is really just a different interface.

PRISM and WCF - Do they play nice?

Ok,
this is a more general "ugly critters in the corner" question. I am planning to start a project on WCF and PRISM. I have been playing around with PRISM some time know, and must say, I like it. Solid foundation for applications with nice possibilities to grow.
Now I want to incorporate WCF and build a distributed application, with one part on a server and two on the clients. It could be even the same machine, or not, depending on the scenario.
My idea is now to take the event concept from PRISM and extend it "over the wire" using WCF and callbacks, like described here WCF AlarmClock Callback Example.
I created a small picture to illustrate the idea (mainly for me), perhaps this makes things a little more clear:
The grey arrows stand for "using lib". The WCF-Event-Base meaning normal PRISM events, where the publish method is called "over the wire".
There are a few questions which come to mind:
Are there any existing known examples for such things?
What will be the best way to "raise" events over the wire?
Any possible problems with this concept (the ugly critters mentioned earlier)
Regarding the second question, I currently think about raising the events using a string (the type of the concrete event I want to raise) and the payload as argument. Something like public void RaiseEvent(string eventType, object eventPayload){} The payload needs to be serializeable, perhaps I even include a hashcheck. (Meaning if I raise e.g. an event with a picture as argument 10 times, I only transfer the picture once, afterwards using the hash to let the server use the buffer when publish)...
Ok, I think you get the idea. This "thing" should behave like a giant single application, using a kind of WCF_EventAggregator instead of the normal PRISM IEventAggregator. (wow, while writing I just got the idea to "simply" extend the IEventAggregator, have to think about this)...
Why do I write this? Well, for feedback mainly, and to sort my thoughts. So comments welcome, perhaps anything I should be "careful" about?
Chris
[EDITS]
Client distribution
There should be an undefined number of client, the server should not be aware of clients. The server itself can be a client to itself, raising strongly typed PRISM events in other parts of the source code.
The main difference between a "client" and a "server" is the actual implementation of the WCF_PRISM connector, see next chapter...
Client Event raising (PRISM feature)
In PRISM, to raise simple events you do NOT even need a reference to a service interface. The IEventAggregator can be obtained via dependency injection, providing an instance of the desired event (e.g. WeatherChangedEvent). This event can be raised by simply calling eventInstance.Publish(23) because the event is implemented as public class WeatherChangedEvent : CompositePresentationEvent<int>
WCF - PRISM Connector
As simple as raising events is subscribing to events. Every module can subsribe to events using the same technique, obtaining a reference and using Subscribe to attach to this event.
Here is now where the "magic" should happen. The clients will include a prism module responsible for connecting PRISM events to "wcf message sends". It will basically subsribe to all available events in the solution (they are all defined in the infrastructure module anyway) and send out a WCF message in case an event is raised.
The difference between a SERVER and a CLIENT is the implementation of this module. There needs to be a slight difference because of two things.
The WCF setup settings
The flow of events to prevent an infinite loop
The event flow will be (example)
Client obtain ref to WeatherChangedEvent
wChanged.Publish(27) --> normal PRISM event raising
WCF_PRISM module is subscribed to event and
send this event to the server
Server internally gets instance of WeatherChangedEvent and publishes
Server calls back to all clients raising their WeatherChangedEvent
Open Points
The obvious point is preventing a loop. If the server would raise the event in ALL clients, the clients would call back to the server, raising the event again, and so on... So there needs to be a difference between an event caused locally (which means I have to send it to the server) and a "server caused event" which means I do not have to send it to the server.
Also, if a client has initiated the event itself, it does not need to be called by the server, because the event has already be raised (in the client itself, point 2).
All this special behaviour will be encapsulated in the WCF event raiser module, invisible from the rest of the app. I have to think about "how to know if event already published", perhaps a GUID or something like this would be a good idea.
And now the second big question, what was I was aiming at when telling about "strings" earlier. I do not want to write a new service interface definition every time I add an event. Most events in PRISM are defined by one line, especially during development I do not want to update the WCF_Event_Raising_Module each time I add an event.
I thought about sending the events directly when calling WCF, e.g. using a function with a signature like:
public void RaiseEvent(EventBase e, object[] args)
The problem is, I do not really know if I can serialize PRISM events that easy. They all derive from EventBase, but I have to check this... For that reason, I had the idea to use the type (as string), because I know the server shares the infrastructure module and can obtain its own instance of the event (no need to send it over the wire, only the arg)
So far till here, I will keep the question open for more feedback. Main new "insight" I just got: Have to think about the recursion / infite loop problem.
Btw. if anybody is completely confused by all this event talk, give PRISM a try. You will love it, even if you only use DI and Events (RegionManager e.g. is not my favorite)
Chris
[END EDIT 1]
This is a very interesting approach. I would say only two things here:
You are really asking for trouble if you use strings and object parameters. Strongly typed EventAggregator events (inheriting from CompositeEvent) are the way to go here. The maintainability will go way up if you do this.
Your model for your WCF -> EventAggregator should consider everything to and from the EventAggregator as an "event" and everything to/from the WCF services as "messages". What you should really consider is that you are essentially translating a EventAggregator event to a message, rather than asking the question "how do I raise WCF events".
I think what you are doing is feasible. Looking at your implementation I really like how you are thinking about it.
Slight Alternative (w/ strong typing)
I wanted to throw a little something out there and see what you thought about it... maybe it will influence your design slightly. Specifically this is meant to address my first point above and go even further with the strong-typing.
Have you considered having EventAggregator-backed implementations of your service interface? Let's say in your example you have an IWeatherService WCF service that you are working with. Currently, as I understand it, your usage will look something like this:
Client uses the WCF Event Client library and calls RaiseEvent("ChangeWeather", Weather.Sunny);
The WCF Event Client library translates this into the appropriate call to the WCF service waiting to receive this message, using the IWeatherService channel interface to do so. Probably with a big nasty switch statement based on the name of the method call.
Why not modify this slightly. Make IWeatherService a shared contract among all of the servers and clients. The servers will have the actual implementation, obviously, but the clients will have EventAggregator-backed implementations that go to a central broker that queues and sends messages to servers.
Write an EventAggregator-backed implementation of the IWeatherService that raises events to be received by a central message broker and throw that implementation in your container for clients to use.
public ClientWeatherService : IWeatherService
{
IEventAggregator _aggregator;
public ClientWeatherService(IEventAggregator aggregator)
{
_aggregator = aggregator;
}
public void ChangeWeather(Weather weather)
{
ChangeWeatherEvent cwEvent = _aggregator.GetEvent<ChangeWeatherEvent>();
cwEvent.Publish(weather);
}
}
From there, instead of using your "WCF Event Client Library" directly, they use the IWeatherService directly, not knowing that it doesn't call the actual service.
public MyWeatherViewModel : ViewModel
{
IWeatherService _weatherService;
public MyWeatherViewModel(IWeatherService weatherService)
{
_weatherService = weatherService;
}
}
Then, you'd have some event handler setup to make the WCF calls to the real service, but now you have the benefit of strong-typing from the clients.
Just a thought.
I really like this type of question. I wish more people would ask this kind of thing on Stackoverflow. Gets the brain moving in the morning :)
It seems like a complicated approach to the problem.
Are you raising the event from the Client application, or raising the events from the service using the callback contract? or both?
I would approach this with a simple service class in the client. It can implement the Callback contract, and for each callback method it can just raise a Prism event locally to any subscribers in the client. If you need to raise events that are handled by the service, then the service class can subscribe to those events and call the wcf service.
All you need really is a class that abstracts the details of the wcf service away from the client, and exposes it's interface through Prism events.
I personally wouldn't want to modify / extend the infrastructure component and create a dependency on the concrete wcf service.