I've created a .Net app, hosted on a secure sharepoint. I want to be able to run this app via VBA (or other apps).
Through asking and research yesterday, I found this is easy to do via Shell filePath, vbNormalFocus - and I can even pass arguments to the app, but what I really want is to control the app as an object, similar to controlling a COM object. After researching and much confusion today I found I can't use COM because this isn't a class library - it's an .exe app (although I've learned SO much today!)
Imagine this type of deal:
Dim x as Object
Set x = Shell "filePath", vbNormalFocus
x.NotSureHowThisWorks
I want to start the app in my Excel environment, and make many calls to and from the app, to give it instructions. The calls could be strings or whatever but the point is I need the running app coupled to an object variable in the VBA code so I can repeat calls and receive responses.
Is this possible?
Since the app is yours, the most simplest thing you can do is to break your app into 2 projects; one DLL and one EXE project. Have the EXE project reference the DLL for all the functionalities, and make the DLL COM-visible then just reference that DLL from your COM application.
If it's meant to be a shared process, then it might be simpler to just run it as a service rather than an .exe.
Related
I'm planning to program an application (C#) which can draw some things on AutoCAD. After a lot of research I don't understand where i need to start. Can someone explain to me what ObjectARX is ? And if I need to use it ?
I want to create an application ! Not an AddOn (NETLOAD)
:)
Sry for my english I did my best.
CM.
Normally applications are independent processes. In some cases the processes may communicate with each other according to some standardized protocol to extend functionality.
Addons, or plugins typically refers to code that is run as part of another process. I.e. you write a library (i.e. a dll file) that is loaded by the host application. This usually requires that the plugin implements some set of standardized interface for it to work.
ObjectARX is according to wikipedia the standardized interface for autocad. It is however for C++ and not for .Net. There is facilities in .Net to use c++ code, and there is also some articles about hosting the .Net environment in a native c++ process.
If you want your "application" to run in a separate process you would need to write a plugin that communicates with your process via some form of Inter process communication method.
All the approach you suggest seem to be rather challenging since it involves several layers of communication that may cause problems. It would probably be significantly simpler to just write a c++ plugin since this is the intent behind the ObjectARX interface.
If you look in the folder where Autocad is installed you will see some managed DLL libraries.
You can create a C# .NET DLL application that references these libraries. Then, you will have access to the AutoCAD environment and can do what ever you want.
Research AutoCAD .NET to find tutorials and resources.
There is some info in the Tag Wiki but, in a nutshell, you cannot create a stand-alone application that directly references the SDK shipped with AutoCAD (or BricsCAD etc). You can automate AutoCAD via ActiveX or you need to buy an SDK from Autodesk (OEM) or the Open Design Alliance and build an app on top of that.
Anything that uses the SDKs shipped with the applications must be a plugin in the host CAD application.
My work has an application written in VB6. I am tasked with writing another, different, application in C# .NET. I am not allowed to change the VB6 code, but I need to call a function (from my .NET application) every time a particular function gets called in the VB6 application.
My boss recommended using COM or DCOM for this task. I am not familiar with either of these topics, and am having trouble finding a tutorial that I can understand easily and that relates to my task.
Can I do this using COM or will I have to modify the existing VB6 code?
You need to expose the function in VB6 as COM (ActiveX DLL). This is straight forward.
http://vb-helper.com/howto_activex_dll.html
Calling a COM Object is easy too.
http://www.c-sharpcorner.com/UploadFile/psingh/CallingCOMComponentFromCSharp12022005231615PM/CallingCOMComponentFromCSharp.aspx
It sounds to me like you have a VB6 application whose source code should not be changed. Now every time a method in the VB6 application is called you also want to call a method in another component (C#).
The above is an assumption since your question is not 100% clear.
If that is the case and you can't change the VB6 application then you might be able to do something using COM Channel Hooks (assuming the VB6 app is composed of COM objects).
But that would be using C++ and low level COM which is probably something you don't want to do.
I think you are asking about invoking a method from your C# application from within your VB6 application. So we are talking about some form of inter-process communication (hence the comment about DCOM).
I've used .NET Remoting to replace DCOM in some applications by creating a COM-callable .NET library to act as the client with the remoting objects being hosted in a .NET application. Your VB6 application uses the objects, and the methods execute on the server.
BUT you will have to modify your VB6 application, at least a little, to inject the new calls to your .NET. Can you be more clear on the requirements to not change the VB6 application?
I'm mixed on how I should design my program. I'll try to be clear, but it's hard to explain!
Basically, I inject a managed C#.NET Dll into a certain process. Right now, this Dll can load any other Dll dynamically via reflection (if the other Dll implement the IRunnable interface).
What I would like to have is the following:
A Master GUI that injects the Dll into a process. You can load from this GUI an extension Dll (via reflection) into the process (all this remotely, the GUI MUST NOT be within that said process). I want the GUI to communicate via WCF or a named pipe. Also, once the said Dll has been load via reflection, it must create a GUI in the master user interface.
I'm really confused on how to approach this problem. Any feedback would be appreciated.
Thanks!
EDIT 1:
Sorry for the late reply I was out of town. I do know how to inject a DLL and starting the CLR into the remote process, that's not a problem. I'll try to reformulate the problem in better terms:
A : Host process (injector)
B : Target process (the one who's gonna get injected)
C : Dll to be injected
D : Dll loaded via reflection from C. Belongs to process B.
Basically, the problem is I would like that once D gets loaded, it creates a GUI window into A. Then I would like that GUI window to be able to communicate with D. How is that possible? Probably I'm looking at the problem the wrong way, but I'm out of idea.
Do you already know how to inject a DLL into another process? This is not completely trivial, and may involve using hooks or modifying the process' memory (of course, both require the appropriate privileges).
Assuming that you do, I would use .NET Remoting or WCF to create a two-way communication channel between the two processes. If you have any more specific questions, feel free to ask.
You won't be able to inject a dll from one process into another. That sort of thing just won't work (even in native (unmanaged) applications). One application can "instruct" (or ask) another "cooperating" application to load a specific dll, provided that dll is available locally on the machine. So application "A" could send the dll to application "B" and ask "B" to load the dll as well.
The way application "A" communicates with application "B" is not so important. If you use named pipes both application will have to be on the same network. If you want this to work across networks (internet) then any tcp technology can be used. Http might be the better choice so you can go past firewalls and such. So Http REST could be one option whether you use ASP.NET or WCF is your choice.
I have some VBA code that needs to talk to a running c# application.
For what it's worth, the c# application runs as a service, and exposes an interface via .net remoting.
I posted a question regarding a specific problem I'm having already (From VB6 to .net via COM and Remoting...What a mess!) but I think I may have my structure all wrong...
So I'm taking a step back - what's the best way to go about doing this?
One thing that's worth taking into account is that I want to call into the running application - not just call a precompiled DLL...
In the past, one way I accomplished something similar was with Microsoft Message Queueing. Both languages/platforms can read/write to a queue.
In my scenario, we had a legacy Access database that we had to maintain. We wanted to migrate away from it and replace it with a more robust .NET solution. To get real time data out of the current system into the new system, we added VBA code to write data to a message queue. Then we wrote a C# windows service to process that data in the new system.
I'm not entirely sure of what you're doing, so this may not be a fit, but I thought I'd mention it.
I've come up with a solution using my original structure...
That is, the VBA application calls a COM wrapper application that translates all of the types from .Net to COM safe types. This wrapper then calls the main service using .net remoting.
The problem I was having was that the common dlls between the wrapper and the service needed to be in the C:\Program Files\Microsoft Office\Office12 folder (along side msaccess.exe).
While I was using the AssemblyResolve method to provide the dlls at runtime, this wasn't working...So for now I'll just have to have the dlls copied to the folder - a far from elegant solution, but at least the communication is working for now.
I am trying to implement an "out of proc" COM server written in C#. How do I do this?
I need the C# code to be "out of proc" from my main C++ application, because I cannot load the .NET runtime into my main process space
WHY?:
My C++ code is in a DLL that is loaded into many different customer EXE's, some of which use different versions of the .NET runtime. Since there can only be one runtime loaded into a single process, my best bet seems to be to put my C# code into another process.
You can create COM+ components using System.EnterpriseServices.ServicedComponent. Consequently, you'll be able to create out-of-proc and in-proc (client) component activation as well as all COM+ benefits of pooling, remoting, run as a windows service etc.
Here we can read that it is possible, but the exe will be loaded as an library and not started in it's own process like an exe. I don't know if that is a problem for you? It also contains some possible solutions if you do want to make it act like a real out of process com server. But maybe using another way of inter process communication is better. Like .Net Remoting.
I cannot recommend this as the way, but you could create a COM-callable wrapper for your C# library, then create a VB6 ActiveX exe project that delegates calls to your C# library.
Why can't you load the .net runtime into you process space? It is possible to host the .net runtime and call into .net using COM.