Passing data between multiple instances of same application - c#

I have a WPF client application which can have maximum of one instance at any point of time, if the user runs the second instance it should pass the input arguments to first instance of application and quit.
i.e i run the first instance with argument "hello", and again starting new instance of same appln with new argument "welcome", noe the second instance should pass the data "welcome" to first instance and exit.
Other that WCF and .Net remoting, is there any easiest and clean way to do it?
Currently I'm able to make the first instance as active, using WindowsEventHandle, but could not able to pass the data. This is in same machine within same login

Have a look at Memory-Mapped Files Since .NET 4 they have been available and can even share memory with unmanaged applications.
Non-persisted memory-mapped files Non-persisted files are
memory-mapped files that are not associated with a file on a disk.
When the last process has finished working with the file, the data is
lost and the file is reclaimed by garbage collection. These files are
suitable for creating shared memory for inter-process communications
(IPC).

Very basic, but you could simply write to a file and have the other application instance monitor the file for new commands with unique IDs for messages based on the current timestamp down to millisecond.

Yes of course. We tried multiple approaches, but the one using mutex`es seems to work the best.
here a some samples :
How can I check for a running process per user session?
a good article about mutex`es http://odetocode.com/blogs/scott/archive/2004/08/20/the-misunderstood-mutex.aspx
a simple implementation
https://stackoverflow.com/a/19326/444149
If You search deeper, I'm sure there's a good sample in SO which shows how mutex events can be used to trigger something in another app instance

Related

Create new process and pass object

I have a batch application that processes a number of inputs to generate some reports. It reads an input text file, generates a list of report definitions, and then calls external code to run each report.
However, the external report generation code contains some sort of memory leak. When running a single report it has no issue, but with multiple the machine will quickly run out of memory. I've tried clearing the report instances and disposing what objects I can, but the only way I've found to clear the memory is to close the process. If I run each report as a separate process, this solves the issue.
So I require my application to create a new process, pass the report definition object and server information, and get that process to generate the report, and then close. Then repeat for the next definition. I have been looking at .Net Remoting using IPCChannel, however I can't figure out how to simply create the process, pass the information (the report definition and server information) and let it run.
Another option could be using memory mapped files. Or potentially using a console application, but that woulds require serializing my object and passing a large amount of text and many arguments, which isn't elegant.
So what option would be best for creating a process, passing a 'report definition' object and server information, and then allowing the process to close before running again?
I suggest you using Named Pipes or Anonymous Pipes. These are specifically for inter process communication and they are very fast. See one example using Anonymous Pipes here: https://msdn.microsoft.com/en-us/library/bb546102(v=vs.110).aspx

Pass informations between separate consoles and windows applications

I have two separate programs, one is a console application, and the other one is a windows application.
My windows application:
Has a graphic interface, buttons, and others functions.
One of the buttons, named "research": when I click on it, I launch the console application with this line of code:
string strResult = ProcessHelper.LaunchProcessWaitForPipedResult("MyExecFile.exe", strArguments, 10 * 60 * 1000, true); // 10 mins max
My console Application:
do a query on all existing files in a directory.
My problem:
I want to create a progress-bar on the windows application to show the progress of the console application. The problem is I don't know how to pass this information between the two processes. The only restriction is to not use a database or file.
Given two processes in the same user session, and wanting to avoid any communication outside that session I would look at three options:
1. Using named pipes.
The parent process creates a named pipe using a random name (and confirms that name is not in use by opening it). It passes that name to the child process. A simple protocol is used that allows the child to send updates.
There are a number of challenges to overcome:
Getting the logic to ensure the name is unique right (named pipe names are global).
Ensuring no other process can connect (the default named pipe ACL limits connections to the session: this might be enough).
Handling the case where a different parent process does not support progress updates.
Handling the child or parent crashing.
Avoiding getting too clever with the communication protocol, but allowing room for growth (what happens when more than a simple progress bar is wanted?)
2. Using Shared Memory
In this case names of objects are, by default, local to the session. By default this is more secure.
The parent process creates a sufficiently large amount of shared memory (for a simple progress update: not much), a mutex and an event.
The parent process then, concurrently with the GUI waits for the event to be signalled, when it is it enters the mutex and reads the content of shared memory. It then unsets the event and leaves the mutex.
Meanwhile to send an update the child enters the mutex, updates and memory and sets the event before leaving the mutex.
The challenges here include:
Defining the layout of the shared memory. Without a shared assembly this is likely to be error prone.
Avoiding others using the shared memory and synchronisation objects. .NET makes things harder here: in Win32 I would make the handles inheritable thus not needing to name the objects (except for debugging) and pass to the child directly.
Getting the sequencing of shared memory, mutex and event correct is critical. Memory corruption and more subtle bugs await any errors.
It is harder to do variable length data with shared memory, not an issue for a simple progress count but customers always want more.
Summary
I would probably look at named pipes in the first place (or perhaps custom WMI types if I wanted greater flexibility). BUT I would do that only after trying everything to avoid needing multiple processes in the first place. A shared library plus console wrapper for others, while I use the library directly would be a far easier option.

How to make a process fire an event in another process in c#/.net?

How to make process-1 able to fire an event in process-2, and send along few argument, to signal the 2nd process to do a specific action, and optionally receive a reply?
It is possible to do this using the filesystem, there could be a file, where process-1 dumps some commands/querys, and process-2 would be constantly reading from that file, but, this solution is not nice.
Any other way to do it?
(I know that its easy in VB.net to fire an event in a running process whenever a new process is started, IF the "single instance" is enabled in the project properties)
You can use named EventWaitHandle to achieve cross-process synchronization.
This article seems to do what you are used to with vb.net single instance (and it seems still a viable option).
In short it seems that there are three approaches to accomplishing single instance like solutions:
Use a Mutex
Cycle through the process list to see if a process with the same name is already running
Use the Visual Basic system for single instance apps (which you can access from C#)
If by "process" you mean "app-domain", it's fairly easy to set up eventing between the two. In fact if you have two classes in two separate app-domains (where each class has MarshalByRefObject as a base class), then .net will automatically set up a remoting structure that will make events appear to behave as they would in a single app-domain. (Example here: http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject.aspx)
The key here though is 'appear'. 'App-domain' and 'process' separation are intended to keep resources isolated on purpose. To access anything outside of your process you really need help from the operating system, like a shared file or internet connection or named pipes - something to that effect. But .net concepts like events don't exist outside of your space in the runtime.
In other words, you'd have to use something like Named-Pipes (http://msdn.microsoft.com/en-us/library/system.io.pipes.namedpipeserverstream.aspx) if both processes are on the same machine, TCPClient/TCPListener (http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx) if communicating across multiple systems, or WCF if you need something more heavy duty.
If you'd like to see a specific example of one of these technologies in practice, I can write one up for you, btw.

.Net/Mono Singleton (Service/Server?) in C# - detect if my .net app is already running and pass command-line args to it

I'd like to create a simple singleton commandline application (a service?) in C# that when it was run, it checked to see if it was already running, and if so, it passed the command-line args to the already running instance and closed itself. Now in the already running instance it would receive the command-line args through an event like "delegate void Command(string[] args);" or something like that, so I can manage command-line through one application via events.
For instance in photoshop, when you open a picture for the first time, it loads a new instance photoshop, but when you open a second picture, it checks to see if an instance of photoshop is already running, and if it is, it passes the picture to the already loaded instance of photoshop so it can avoid the costly load-time of photoshop all over again...
Or in the web browser, you can set it so if you open a new .html file, it opens it up in a new tab, not a new window instance.
or many text editors have settings to only allow one instance of the text editor open and when a new file is opened, it's loaded in a new tab, not a new window...
many music players like winamp do this too...
I am going to eventually be setting this up as a service, so it should be constantly listening for command-line args later, but for now it's mostly so that I can manage the opening of files of a specific type together in one singleton application, or have other applications pass command-line arguments of files they want to be opened...
Also, if you know a better way or an api in .Net to re-rout all command-line args passed, to an event of a service that is always running, I can work with that... but I'd also like to keep this cross-platform so it can run in Linux/Mac on Mono if that's possible, without having to manage two or more code-bases...
This is the article i used to implement the exact functionality that you are looking for, it allows you to transfer command line arguments as well.
Single-Instance C# Application - for .NET 2.0
We did something simillar using although for a very different purpose using .net remoting on 1.0 / 1.1 framework. Basically we'd use a semaphore to ensure we were the only running instance. You'll want to target the global namespace, if you want to have only one instance per machine or the local if you want one per user session (In terminal service and fast user switching scenarios).
If you can lock the semphore, you will setup remoting and start listening for events, and then continue on with your code.
if you can't lock then you can asssume you have another running instance in which case you'll open up a remoting channel to the other instance pass the args and shutdown.
You could try using a named mutex (naming it will make it system wide, and easily identifiable). With the mutex, you can either run the instance (if no mutex exists with the name), or you can open the existing instance and pass in your parameters.
Apologies for no code sample, writing this from my phone.
Edit: nvrmnd. Just reread the post, and I don't think this will work for you going cross platform.
Visual basic has this built-in. Take a look at:
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase -- Public Event StartupNextInstance

How to query a variable in another running application in c#?

I have an app that, when launched, checks for duplicate processes of itself.
That part I have right - but what I need is to check a state variable in the original running process in order to run some logic.
So: how do I make a variable (e.g. bool) available publicly to other applications so they can query it?
There are a bunch of ways to do this. A very primative way would be to read/write from a file. The old win32 way would be to use PostMessage. The more .NET way would be to use remoting or WCF and Named Pipes.
.NET 4 is also getting support for Memory Mapped files.
Here is a pretty thorough looking artcile describing a few different approaches including support for Memory Mapped files outside of .NET 4
http://www.codeproject.com/KB/threads/csthreadmsg.aspx
The easiest: Create a file, and write something in it.
More advanced, and when done correctly more robust, is using WCF, you use named pipes to setup some communication channel on the local computer only.
If you're using a Mutex to check whether another process is running (you should be) you could use another Mutex whose locked state would be the boolean flag you're looking.
The standard way of doing this is to use the Windows API to create and lock a mutex. The first app to open will create and lock the mutex. Any subsequent executions of the app will not be able to get it and can then shutdown.

Categories