I'm working on a project requiring inter-AppDomain-intra-process and inter-process-intra-machine communication. Yes... I know... NET Remoting is widely considered a legacy technology but I'm facing with two very special problems and maybe in these scenario WCF is not a full replacement of NET Remoting.
1) inter-AppDomain-intra-process communication
The application I'm working on start and need to search and load one on more addins. I wish to load each addin in a separate AppDomain. I need a way to create the each Addin instance in his AppDomain and call some interface methods of this instance at some point. Here NET Remoting is the only way, right? Moreover if we wish to apply the System.Addins paradigm, apparently based only NET Remoting and not marked as obsolete...
2) inter-process-intra-machine communication
Here I can for sure expose from my application a WCF service and call this service from my client using Named Pipes.
What I really want to do is to expose an object model from my application, so that my application can be automated from some NET client, much like the OLE/COM Automation object model exposed by Excel. Any COM Client can get an object reference to Excel.Application and query open documents, open some new documents and so on.
I think WCF is good to communicate in a platform independent way. But in this case I need only to communicate from Net client to Net application on the same machine. WCF service phylosophy don't allow, I think, to expose a rich object model with objects, collection, field, static member, method overloading... Or I'm wrong?
Please excuse my bad english and my perhaps newbie question.
You can read answers to a similar question here: Is .NET Remoting really deprecated?
I can add that I used .NET Remoting recently for relatively simple bi-directional inter-process communication, and all went almost seamlessly, so I can say it is still very usable after all the years of not being actively supported by Microsoft.
As for COM, if you have strong requirements for your product to be accessible by COM-clients, I would suggest to implement COM interfaces explicitly, via COM interop. Also, there is an interesting article about using COM and .NET Remoting together that might be of interest: http://msdn.microsoft.com/en-us/magazine/cc164085.aspx
Related
So I plan to have a button on my GUI of my .NET Application which controls the service. I wanna stop the service when a button is pressed. I want to achieve this with an argument passed between the VB.NET application and the service.
As far as I know, there are 4 available technologies in inter-process communication:
.NET Remoting
WCF Anonymous Pipes
WCF Named Pipes
Memory Mapped Files
What technology is the best one to implement those functionalities?
As this is my first approach with IPC I thank you in advance for in-depth answers :)
According to #MatSnow 's comment under the original question the Service Controller might be the best choice for this problem.
ServiceController Class Stop Method
I was searching MSDN and several other Access forums for creating custom Access API's, but didn't see anything related. Is this possible? Can custom ODBC's be created for Access?
Hum, this is confusing since it not clear if you are talking about building interfaces with Access to OTHER systems, or are you talking about a building an Access interface that other programs can use?
ODBC is a "driver" provided by vendors to allow use of their SQL database systems and is something that you don't create in Access or FoxPro or in VB for that matter. In fact I can't think of any data centric tool that would allow you to build your own ODBC driver. So this suggests some confusing here.
Extending Access.
Access for the last 20 years has had the ability to consume ActiveX (COM objects). So how one extends the ability of Access to communicate with other software and systems REMAINS the COM object choice. So for example one can use the MSXML library from Access (a COM object) and this allows one to consume web pages, and specify XML which opens the door to consuming web services. In fact I used MSXML to consume SharePoint web services for example.
However for consuming web services it is usually far better to build COM object with tools that can "already" consume web services. So one would use vb.net to create a COM object and THEN reference that COM object from MS Access (so just like we set a reference to outlook or word from Access, such COM objects are not limited to applications you purchase, but you are most free to create your own COM objects VB6, vb.net, c# or whatever).
Access does NOT have the ability to create ActiveX (com objects), but it certainly can consume ones you build in other languages.
NOTE: I am using the term ActiveX and "COM object" interchangeability here – they are the same basic technology.
So if you ever used a desktop computer and any windows development tool, you find that "COM" objects are the choice and REMAIN the choice of how to extend Access, or even that of VB6. With managed code, things change somewhat, but vb.net is quite happy to create COM objects that work well with Access.
While Access cannot as a tool create ActiveX (com) objects, you can certainly compile Access code into an accDE and THEN reference that library code from the VBA tools->references. So you can extend and share VBA code in one library with "many" applications, but this is not a com object.
So just like in the past to extend desktop programs, you can build such extensions as COM objects and consume them from Access – this is the standard approach to extend Access to say consume web services.
Access cannot be used to build individual COM objects as UI parts, but the STANDARD means in our industry to create COM objects is able to be consumed by Access.
Last but not least:
Any application you build in Access CAN BE CONSUMED as a COM object by other applications. So while you cannot build individual COM objects, your WHOLE application is in fact a com object.
So if you build an Application in Access then using Excel, VB6, FoxPro, another Access application, C++, or C# or vb.net? They ALL CAN consume your application as a com object by simply creating an instance of Access and your application.
So any development tool that supports "com" can consume your application as a com object. So any standard development tool, article or system for the last 20 years can consume your Access application as a COM object.
So while Access cannot create individual COM objects, the resulting Access applications are in fact a legal com objects that ANY application that supports COM can create an instance of your application. This means your code and VBA subruties etc. are callable from the host application that created the instance of your application. In theory any VBA code exposed as "public code" are thus able to be called from that other program.
So the "interfaces" available to Access remain the SAME as the near 20 year history of MOST desktop programs running on windows – that interface is COM.
So you have 20 years of history and 20 years of examples on the internet to have fun with - any example that shows how to create and consume a com object should work for your access application.
I intend to add a COM interface to an existing application (which, by the way, is written in C++ using Win32). I have some experience using COM objects, so I know the basic COM concepts of interfaces, etc., but this is the first time I'm actually implementing a component.
Ultimately I want to be able to use the COM interface to automate my application from scripts such as VB. I understand that there are two steps:
My application must act as an out-of-process server (i.e. I have to use MIDL and generate code for a proxy DLL and a stub DLL).
Once I have the server I can add automation capabilities by implementing the IDispatch interface.
Since the server-in-an-EXE thing with MIDL and what not is already a bit steep, I wanted to get a grasp on all that first before moving on to IDispatch.
I am reading the book "Inside COM" by Dale Rogerson and have completed the chapter on servers in EXEs (the following chapter will cover Automation).
The "Servers in EXEs" chapter provides example code that implements a server and a client. But it is necessary to start the server manually. This confuses me. Obviously, when my application (= server) is used by a client process, this extra manual step should not be necessary. Is there no mechanism to start the server automatically? Or is automation necessary to achieve that? At the moment, the prospect of having to start my server manually (once I even have one) makes me doubt I am moving in the right direction.
Hopefully someone with more knowledge of this can see what information I'm missing and point me in the right direction.
No, COM servers are not normally started by hand. Not sure why the book proposed it, possibly because it wanted to avoid talking about the registry keys you need to allow COM to automatically start the EXE. It isn't otherwise very complicated, you register the Application coclass of your app with the LocalServer32 key value giving the path to the EXE.
It is however not completely uncommon, especially with an existing program. One design decision to make is whether you let the client code completely control your program. Or if your program already has an existing user interface but you also want to expose services to other code. In the latter case it makes sense to let the user start the app by hand, like she'd normally does.
When your application is registered as LocalServer32, it will be invoked with the commandline specified there if no running process has registered a factory object for your CLSID yet.
This way, you can get the best of both worlds -- if the application is running already, this instance can provide the server side, and if it isn't, it will be started.
Automation is completely orthogonal to that -- your component becomes Automation compatible by implementing IDispatch.
I understand that COM is really a way to program (i.e. like structured programming, or OO programming). However it is a little old. So I was just wondering what has really replaced this set of specifications? Will I find this in .NET documentation?
COM has not been replaced. The Component Object Model is a core part of Windows and will remain so for the foreseeable future.
COM provides you with one mechanism of inter process communication (communicating between applications on a machine), it is also used as a much simpler (for the consumer) system of sharing dlls. Its COM (or ActiveX, or OLE - all the same) that enables VBA to work so well in MS Office, it is the foundation of ActiveX controls.
COM is not a way to program (unlike OOP etc) it is a technology that works on windows to make access to other applications during runtime easier.
.NET can use COM object with wrappers, and if you want to allow any app to access your functionality, its still best to provide a COM wrapper.
Other methods of inter app coms now exist such as ZeroMQ.
The original specification for COM is old in age, but the specification as well as the concepts are still in use, and you can still create and consume COM objects.
For .NET, you can start by looking at the following links:
Com Interop Part 1: C# Client Tutorial (C#) # MSDN
Interoperating with unmanaged code # MSDN
In addition, there are other specs that are very similar to COM or have semantics that are the same. Most notably, XPCOM is in use in FireFox for their plugin spec and also used internally to FireFox to connectable objects.
XPCOM # MDN (Mozilla)
WinRT is an upcoming platform update for windows that is also heavy in COM concepts.
There are some useful here: Why is WinRT unmanaged # StackOverflow
For .NET developers, a lot of the declarative overhead is hidden as mentioned here: WinRT demystified - Miguel de Icaza
The head of the spec is here: The Windows Runtime # MSDN
And in the context of COM, developing WinRT components with C++ has similarities, although some syntax is borrowed from managed C++: Creating Windows Runtime Components in C++ # MSDN
It's hard to explain our situaction.
We have a 3-tier application. The engine is a DLL coded in C++, then we have a VB6 ActiveX EXE that access to the engine via API calls, and at the top level we have a Excel Addin (in C# using VSTO framework) calling the middle layer with an interop DLL. At this time, each "connection" from the Addin to the engine creates a new EXE (VB6 uses API calls to access to the engine) and all works fine.
Now we are moving the middle layer to .NET, it works 'presumably' fine (it pass all our Unit test) but, we found an error when we open 2 "connections" at same time (ups, no unit test check this situation because it's a new behavour). The DLL have static objects that it's shared over all instances in the same process and we have interactions between "connections". In our old version each "connection" creates a new EXE with no memory sharing between processes, now it's the same process and they share memory and the static objects.
Following the tips from this question. We tried to build a COM EXE in C# to do an out-of-process objects in the middle layer but we have the same result. They share the static objects, at the end, each connection not creates a independent process.
It's clear, but not affordable at this time, moving API calls to ATL or changing the static objects to instanciable references with a handle and change all the API calls to get/set this handlers. I reviewed all examples in MS All-in-one but I didn't find any solution. Neither it's possible to keep only one connection at time, each workbook can have one connection and in the future we want to explore a Web application with multiple connections at same time.
Any suggestion?
Thanks in advance,
Whether COM starts new EXE per each COM object, or uses single EXE to instantiate all the object is controlled by flags parameters passed to CoRegisterClassObject. See
http://msdn.microsoft.com/en-us/library/ms693407(v=vs.85).aspx, and
http://msdn.microsoft.com/en-us/library/ms679697(v=vs.85).aspx
You need to pass REGCLS_SINGLEUSE or REGCLS_MULTI_SEPARATE flags.
Now, the trick is to pass this flag, as you might not call this method directly - the details depend on how you implemented the COM EXE.
it's not clear from the question, but it sounds like the "middle layer" you have was built as a VB6 EXE, and you're trying to replace it with a .net DLL. If that's the case, you'll definitely get the behavior you describe.
With a VB6 EXE com project, instantiating a new object starts a new process. With a .net dll (or a Vb6 dll really) you +won't+ get a new process.
You'd either need to create a .net EXE that exposes COM objects just like your VB6 exe does, or (sounds like you've already investigated this) you'll need to refactor your EXE objects to properly handle multiple instances within a single process.
Honestly, it'd probably be better to do that latter, since relying on singletons like this is generally a bad code smell. But it a pinch, you should be able to replicate the behavior of the VB6 exe with a .net project. You just can't do it in a dll.
Was your middle layer created in .Net? If it was, you might be facing the issue that your COM class is been created as a native .net object instead of a COM object. The solution usually involve using Primary Interop Assemblies. Take a look on this SO question to see if it matches your problem.