I have two programs that call a dll. I want to have them both make sure to call the same instance of the dll so it can be used to pass information back and forth.
How can I correctly pinvoke the same instance so that both programs are talking to the same dll and information can be passed back and forth using the dll as an intermediately with reverse pinvokes and callsbacks.
Is pinvoke not the way to do this? Is there a better way?
It is called "shared section in DLL" and it would let your somehow share data between all processes that load that DLL.
You will not be able to share callbacks as code is running in different processes. You need some sort of IPC (inter-process communication) mechanism to do that.
Overall I would recommend against doing it as it is unusual approach to sharing data between applications. You will unlikely to find help and samples how to do that and would need to read the book (Windows Internals, useful read anyway) to do it properly on your own.
Use Interprocess Communication with WCF
DLLs are used for shared code, not shared data.
Related
We have layered architecture that has a native C++ client, and a managed client C++/C# wrapper around it. (2 dll files, one native one managed)
These two clients go through a COM layer to a C# service, there are many different versions of these clients and the service is designed to be backward compatible.
Recently we realized we might need to know the version of the client calling into the service. (the dll files)
Is there a way to go through the call stack and grab the dll that called in and its version? Does going through the COM layer make this an impossible task?
Other products consume and deliver these clients, so the location or path of the dlls is not always known. Getting the location through the call stack might be an alternative route to the solution, but I might be thinking about this entirely incorrectly.
We can't edit existing released client dlls, so we have to be able to determine the version of the dlls from the service layer at runtime.
It is possible to capture a stacktrace, step thru the various stack frames, get the methodinfo for each, get the declaring type, and find the assembly for that type. This however is rather cumbersome, and would be slow since it would use a lot of reflection. I'm not sure if COM would affect this, but I suspect it should not, as long as the call does not jump between threads.
This would also be rather poor practice since the method call depend on information that is not obvious for the caller. As such it can be very confusing for new developers, and may be fragile.
Perhaps it would be sufficient to check what dlls are loaded, rather than what version made the call?
I would recommend making your service work correctly regardless of client if at all possible, possibly adding information to the call if needed. Another approach is to specify multiple versions of the service, and let the client call the version it has been developed with. Third approach would be to explicitly inform the service about the client version, and if this is not done, assume some specific client version.
I'm working on a project that involves receiving a byte[] from a web page in a .net program, then loading that byte[] as a dll. However, the dll is not a .net assembly, it is a native assembly. I can't use loadlibrary because I would have to write to disk, and I want to keep the native dll in memory. I can't use c++ /cli, because this is all being done in mono, and mono doesn't support c++ /cli. Is there a library or project somewhere that allows me to load a native dll from a byte[], in c#? I've seen this tutorial: https://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/, but this is c++.
This will help you, or lead you somewhere.
This is basically a wrapper for the project you have sent, I will keep the repo up for anyone who wishes to look at It. Untested on 32bit OS, so It might do an overhead.
https://github.com/dretax/DynamicDllLoader
It basically does what you want. Expects a native dll's byte array, and loads it into the current process.
Just use Assembly.Load (if that's .Net assembly) https://msdn.microsoft.com/en-us/library/h538bck7(v=vs.110).aspx.
Otherwise, use PInvoke with unmanaged DLL's.
I will give you a short rundown on where problems with that lie:
You are receiving a DLL from the internet. Every adminsitrator will wonder if he just got insane or that really stands in the "how it works" description. We had enough problems with remote code excecution and code injection on data arrays in the last century to know how this will fail without needing to try.
Anything in the design of the managed .NET Runtime is there so you can not do shit like that. You propably have to go to unamanged code. And at that point, you might as well write in native C++.
It might even trip over some run off the mill virus scanners heuristics just for trying to pull this. Because that is on the short list of things a visitor to my Operating System should never try to pull.
You really, really should just burry that idea and live without it. If you got a boss that wants this, say him it is between impossible and figuratively insane. Possibly even literally insane. Even if you could make it, no admin of sound mind would install it.
If that has not detered you: It might be best to move this into a helper process of some sort, then transmit data/results via Interprocess Communication. When calling old, umanaged, never-migrated-to-64-bit DLL's from a .NET Application, missmatching binarity is often a problem. A helper process (that always runs at x32 to match the DLL) can help with that. And once you got a helper process, it can be programming in something like Native C++ where these kinds of shenanigans are easier and you even go a example.
Ok so the scenario is as followed.
Application1 has the ability to load and make calls to an unmanaged C++ DLL.
I want to write another user interface in C# to make my life easier.
I then want the DLL to be able to send information to the C# executable, and the C# executable to be able to send information to the DLL.
The information being passed back and forth is not complex. It will simply be a string.
Any ideas on how this can be done.
This should answer your question. Basically the easiest options are Named Pipes for communication on the same machine, and Sockets for different machines.
Update
After better consideration, the answer depends on 'Who is in control?' in your scenario.
1. If C# executable is responsible for calling your unmanaged DLL and sending/retrieving information, then you should go with Platform Invoke.
2. If you you want your unmanaged DLL to decide when to send data to the application, then first of all you should transform your DLL into full fledged application and after that go with the interprocess communication.
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.