I have a .NET C# WPF application that I am trying to make into a single-instance application using a Mutex.
This .NET application is called by a C++-based DLL using CreateProcessAsUser() and is given parameters via environment variables.
Subsequent instances will also be created by the C++ DLL in the same way.
Subsequent instances would then need to pass their parameters to the first instance of the application before exiting.
The problem is what methods can be used in the .NET application so that the subsequent instances would be able to pass their data to the first instance of the .NET application? The simpler, the better.
I have researched some but I hope there are simpler ways.
Things I have researched:
Named Pipes
.NET Remoting
Windows Messaging (Sending WM_COPYDATA to the first instance window)
Since I am just trying to pass 4 strings to the first instance, I am trying to avoid the above mentioned methods because they are somewhat overkill for my problem.
The simplest I can think of is to export a function from the .NET application so that the subsequent instances of the .NET application can just call this function on the first instance of the .NET application and pass the data as the parameters of the function. However, is this possible in .NET? I've read that .NET EXE or DLLs could not export functions.
Thanks!
The simplest I can think of is to export a function from the .NET application and then the subsequent instances can just call this function and pass the parameters to it.
This is not how this works. You'll load the .NET assembly in the calling process, not magically cross the process boundary and talk to the child.
Just have the parent open the child with redirected pipes using the Process class, and have the child read from stdin using Console.Read*
thanks for the reply, Paul!
I've added more detail to my question above, though, coz I'm not sure if my scenario was understood correctly.
But regarding your answer, the parent of the .NET app will be a C++-based DLL and all it will do is call the .NET app and give it parameters. The C++-based DLL will also exit after this so I wouldn't want to add anymore behavior to it.
So, passing of data would then be done between the instances of the .NET applications only.
Since you are going from .NET to .NET, I'd recommend just doing a WCF call. You can use a named pipes transport between the two .NET instances to expose the "service" (which is what your first instance would expose).
Subsequent instances would do the single instance check, and if they detect an already running instance, they could make a WCF call to the service running in the first instance and pass the data that way.
Related
Recently i discover that running few instances of method compiled to .exe is faster than running the same method in f.e. few new Tasks. I don't know if that applies to every method, but it does to getting data from API.
I was searching internet to find answer how to manage that. I got answers to try run method in new appDomains. So i create .exe assembly with methods that i want to be run (it is Console application). I Load it by right click on References -> Add Reference. I could easily access that method by exeName.ClassName.Method(params). The thing is that I don't know how to run this methods in new appDomains. Every answer that i found in web was with loaded assembly by path.
I will also be very happy for answers other than creating AppDomain. I just want to pass data to this method and get results.
TL;DR: Method run in Parallel.For(0,4,i=> method()) works slower than run the same method in 4 instances of compiled .exe file.
You could use a multi process architecture using IPC protocol or host your methods inside different domains. In both situations i recommend .net remoting over wcf because you would write almost the same code for both aproaches and because for talking to a class found in another app domain hosted in the same process, .net remoting is the only way (sadly for many devs but not for me). BUT I am almost sure that generally this would NOT be more faster than just creating some threads and calling them asinchronous. Inter domains / process communication must rely on message serialization/ deserialization that adds huge overhead, specially if the method call itself is very light.
After some researching and asking i found solution:
var ad = AppDomain.CreateDomain("mydomain");
ad.DoCallBack(() =>
{
//stuff to do
}
Probably there'll be some issues with passing data to new AppDomain. Easiest way for me is:
ad.SetData("key", value);
and to retrive in AppDomain:
var value = (valueType)AppDomain.CurrentDomain.GetData("key");
I need to create a desktop app in C# that will require a specific set of parameters when loaded, either by command line (or a direct reference?) from an old VB6 application or as a reference from a vb.net application.
I need parameters such as name, city, state, zip and a few others. I'm not sure yet what all I'll need yet. I know I'll need some very basic account information to be passed in.
What would be the best way to accept these parameters where they can be called from either application?
I started to create a class that contained the needed parameters, but I am not sure if a VB6 application can reference the exe as a dll and pass a it the class back. I've not called a .net application from vb6 so I don't know the requirements and I don't have vb6 installed.
Any suggestions?
Write a DLL/library. Then write an EXE that takes the parameters and just references that DLL the same as other code would.
This may help, Command Line Parameters Tutorial
http://msdn.microsoft.com/en-us/library/aa288457(v=vs.71).aspx
I'm currently automating an application at work using COM, and have an issue where anyone using my application has a problem if the original application is already open when my application runs. I know how to locate the process if it's open, but instead of having to worry about closing it, or working around it, etc., I want to try to use the existing application instead of opening a new one.
This is how I normally start the application in my automation program:
Designer.Application desApp = new Designer.Application();
Now I'm attempting to try and use the handle from an existing application:
Designer.Application desApp = (Designer.Application)((System.Diagnostics.Process.GetProcessesByName("Designer.exe")[0]).Handle)
(I know this doesn't work, since .Handle returns an IntPtr, but I'm using it as an example.)
Is there any way to accomplish this? How do I return a usable object if I know the handle/process?
The COM way of attaching to an existing automation object retrieve the object for the Running Object Table (ROT) http://msdn.microsoft.com/en-us/library/ms695276(VS.85).aspx.
You can use the IRunningObjectTable interface to register your COM objects in the ROT.
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.comtypes.irunningobjecttable.aspx
And use to query the ROT for an existing instance of your object. System.Runtime.InteropServices.Marshal.GetActiveObject for example.
You cannot make this work in the client code, it has to be dealt with in the server. The server must call CoRegisterClassObject(), passing REGCLS_MULTIPLEUSE so that multiple clients are allowed to use the single server instance. There is no other mechanism to allow a client to obtain an interface pointer to the Application object.
This is very much by design, the server has to be designed and written to support such usage. It cannot be bolted on later.
That's what I wanna achieve :
There will be dll which contains only methods which calls my actual methods from my application and I can share that dll with outside world regardless of which methods it includes because actual methods will be in the dll in my application but if some one uses that outside dll he/she can manages to get my application to do something in limits of I desire.
I hope I could describe what I want. I don't know if you have ever used Skype4COM.dll. It actually works like that, it somehow connects to Skype Client and let me call some one I want. For example :
Skype s = new Skype();
s.PlaceCall("phoneNumber");
I import Skype4COM dll in my project and when i write code like above in C#, it connects to Skype and make a call.
I think there is no actual methods which makes calls in Skype4Com.dll. I think it only does have some sort of methods which reach actual methods in Skype API and make the call so whatever the developers change in Skype, it doesn't affect Skype4Com.dll wrapper as long as signature stays the same.
So, that's what I want to achive, I am not quite interested in writing wrappers tho, that was a sample case, I want to write a dll which reachs my API and uses method signatures and let people use the application from outside so as long as the signatures stay same, if I want to change something between block I don't need to change the dll given out to outside..
Thank in advance....
If I understand you correctly, you want to expose a limited subset of the functions of your application to outside users. In effect, you want to offer a service, but nothing else.
Then you should use Windows Communication Foundation to host a service inside of your application (or elsewhere). This service could use industry-standard protocols like SOAP; or could use REST; or it could use faster binary transfers over TCP/IP for your .NET clients.
It's perfect for a service-oriented situation like yours.
What you're describing is a COM wrapper around Skype. If you really want a COM wrapper around your C# DLL, you can do that. Microsoft has provided an example that demonstrates how to create a COM Class from C#.
If you're looking into providing a wrapper around your code from managed DLLs, then it's as simple as providing a public interface that consumers of your DLL can use. You'll probably also want to install your code in the GAC (Global Assembly Cache) so that anyone that wants to call into your API can do so without putting copies of your code all over their system.
You could make everything internal instead of public inside this DLL. Internal keyword restricts access to classes, methods or properties to assembly while public keyword allows access from other assemblies
I currently have a .NET class library written in C# that exposes its functionaility via COM to a C++ program (pre-.NET).
We now want to move the library out-of-process to free up address space in the main application (it is an image-processing application, and large images eat up address space). I remember from my VB6 days that one could create an "OLE automation server". The OS would automatically start and stop the server .exe as objects were created/destroyed. This looks like the perfect fit for us: as far as I can see nothing would change in the client except it would call CoCreateInstance with CLSCTX_LOCAL_SERVER instead of CLSCTX_INPROC_SERVER.
How would I create such an out-of-process server in C#? Either there is no information online about it, or my terminology is off/out of date!
You can actually do this in .NET (I've done it before as a proof-of-concept), but it's a bit of work to get everything working right (process lifetime, registration, etc).
Create a new Windows application. In the Main method, call RegistrationServices.RegisterTypeForComClients- this is a managed wrapper around CoRegisterClassObject that takes care of the class factory for you. Pass it the Type of the managed ComVisible class (the one you actually want to create- .NET supplies the class factory automatically) along with RegistrationClassContext.LocalServer and RegistrationConnectionType.SingleUse. Now you have a very basic exe that can be registered as a LocalServer32 for COM activation. You'll still have to work out the lifetime of the process (implement refcounts on the managed objects with constructors/finalizers- when you hit zero, call UnregisterTypeForComClients and exit)- you can't let Main exit until all your objects are dead.
The registration isn't too bad: create a ComRegisterFunction attributed method that adds a LocalServer32 key under HKLM\CLSID(yourclsidhere), whose default value is the path to your exe. Run regasm yourexe.exe /codebase /tlb, and you're good to go.
You could always expose your .NET class as COM classes using InteropServices and then configure the library as a COM+ application. The .NET library would run out-of-process and be hosted by a DLLHOST.EXE instance.
Here is an article in MSDN that covers all aspects of how to create COM localserver in c# (.net): link
Your post started a while ago and I had the same problem. The following link is absolute gold and tells you everything
http://www.andymcm.com/blog/2009/10/managed-dcom-server.html