On Windows/.NET, a named Mutex can be used to synchronise multiple processes. Unfortunately, Mono doesn't quite support this on Linux. Their release notes say that Linux doesn't support this Windows feature and it would be unreliable to emulate it. It seems best to avoid the proposed hack to enable it anyway.
So what are suggested alternatives? I need to make my program safe to run concurrently, only a short section of it needs to be synchronised with other instances.
The application eventually needs to be deployed on Ubuntu Linux with Mono 2.10, but for testing, it would be highly appreciated if it also works on Windows 7 with .NET 4.
UPDATE:
Try to look at http://aakinshin.net/en/blog/dotnet/namedmutex-on-mono/
OLD:
Mono does not support any Windows-native IPC.
So you do not have for example Named Pipes, or Mutexes.
But to sync threads in the same process you can use Monitor class explicitly (it also used for lock).
To simply notify another process you can try to use Unix Domain Sockets.
Check UnixEndPoint class for that. One of benefits you can specify name for it (like for named semaphore for example).
Also you can try to emulate Mutex using own file. Try to get exclusive access to specific own file. While you have that access - you are in critical section.
Related
Let's say, I am executing an exe written in c#(just my choice of language). It has the following piece of code:
var comObj=new ComClass();
comObj.DoSomething();
Now, I would like to know in which process is the DoSomething method executed. Is it the same process where the current exe is running or a different process responds to the DoSomething call?
This is entirely transparent in COM, you cannot find out from your program either. It is determined by configuration information that is stored in the registry. The core reason why COM servers need to be registered. The different scenarios are:
On the same thread that creates the object. Used when the server is registered as an in-process server and the thread's apartment is compatible with the threading model of the COM object. The most common case, particularly so when you create objects on the UI thread of a program.
On another thread, if necessary created by COM, to give the object a thread-safe home. This commonly happens when your new statement runs on a thread that's in the MTA, the multi-threaded apartment. Commonly from a worker thread. The object you create is a proxy, its primary job is to serialize the arguments you pass to a method and deserialize them in the stub which runs on the other thread. It ensures that all calls on the object are thread-safe. Otherwise the same kind of mechanism as used in .NET Remoting. The underlying layer that takes care of the marshaling is LRPC, an obscure Windows component that was optimized to make inter-thread and inter-process calls as fast as possible.
Inside a surrogate process for an in-process component. Not very common but surrogates can be very handy to bridge a process bitness problem for example. Allowing you to use a 32-bit server in a 64-bit process. Requires both 32-bit and 64-bit proxy/stubs.
Inside another process that was registered as an out-of-process server. The canonical example are Microsoft Office programs like Word and Excel, very common in .NET programming. This is where COM starts to get brittle, unexpected program aborts tend to cause a mess when the server keeps running. A very common question at SO.
Inside another process on another machine. Called DCOM or Distributed COM. An extra configuration step is necessary to ensure the target machine and proper account privileges can be selected. Pretty notorious for giving humans a splitting headache, it doesn't get used much anymore these days. DCOM's biggest claim to fame was enabling Java to eat Microsoft's lunch in the middle-ware wars of the late 90s.
If you have no idea which of these scenarios applies in your case then a utility like SysInternals' Process Monitor tends to provide insight. You'll see your program reading the registry, telling you where to look, and load a DLL or start an EXE.
From COM Clients and Servers
There are two main types of servers, in-process and out-of-process. In-process servers are implemented in a dynamic linked library (DLL), and out-of-process servers are implemented in an executable file (EXE). Out-of-process servers can reside either on the local computer or on a remote computer.
I do think that the names are quite explicit :-)
Note that even for out-of-process COM servers, there will be some code in-process that will do the marshaling between the COM client and the COM server
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.
I would like to provide a large number of inhouse .net applications with a lightweight way to announce that they are being used. My goal is to keep track of which users might benefit from support check-ins and/or reminders to upgrade.
This is on an inhouse network. There is definitely IP connectivity among all the machines, and probably UDP. (But probably not multicast.)
Writing to a known inhouse share or loading a known URL would be possibilities, but I would like to minimize the impact on the application itself as completely as possible, even at the expense of reliability. So I would rather not risk a timeout (for example if I'm accessing some centralized resource and it has disappeared), and ideally I would rather not launch a worker thread either.
It would also be nice to permit multiple listeners, which is another reason I am thinking about broadcasting rather than invoking a service.
Is there some kind of fire-and-forget broadcast mechanism I could use safely and effectively for this?
There are certainly many options for this, but one that is very easy to implement and meets your criteria is an Asynchronous Web Service call.
This does not require you to start a worker thread (the Framework will do that behind the scenes). Rather than use one of the options outlined in that link to fetch the result, simply ignore the result since it is meaningless to the calling app.
I did something similar, though not exactly a "braodcast"
I have an in house tool several non-techies in the company use. I have it check a network share for a specific EXE (the same EXE you would download if you wanted to use it) and compares the version # of that file with the executing assembly. If the one on the network is newer, alert the user to download the new one.
A lot simpler than trying to set up an auto updater for something that will only be used within the same building as me.
If upgrading is not an issue (i.e. there are no cases where using the old version is better), you can do what I did with something similar:
The application that people actually launch is an updater program, it checks the file version and timestamp on a network share and if a newer version exists, copies it to the program directory. It then runs the program (whether it was updated or not).
var current = new FileInfo(local);
var latest = new FileInfo(remote);
if (!current.Exists)
latest.CopyTo(local);
var currentVersion = FileVersionInfo.GetVersionInfo(local);
var latestVersion = FileVersionInfo.GetVersionInfo(remote);
if (latest.CreationTime > current.CreationTime || latestVersion.FileVersion != currentVersion.FileVersion)
latest.CopyTo(local, true);
Process.Start(local)
I also have the program itself check to see if the updater needs updating (as the updater can't update itself due to file locks)
After some experimentation, I have been getting good results using Win32 mailslots.
There is no official managed wrapper, but the functions are simple to use via PInvoke, as demonstrated in examples like this one.
Using a 'domain' mailslot provides a true broadcast mechanism, permitting multiple listeners and no requirement for a well-known server.
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.
How to get currently running application without using a system process?
It depends on what you look for. If you are interested in the assembly that is calling you,then you can use GetCallingAssembly. You could also use GetExecutingAssembly.
Slight misconception here. On any given machine there can be multiple current running process. Consider the case where the machine has multiple CPU's. It's possible, and in fact likely, that each CPU will have at least a separate thread running on it. There is a very good chance that at any given time the number of processes currently running on the machine will be close to the number of processors on the system.
In the case of a single processor the act of getting the current running process is redundant. It will simply be your application.
If you want to investigate processes running on the current machine without using the Process class, you can PInvoke into the Process32First and Process32Next system calls.
If you're using .NET, whatever mechanism you end up using, make sure that you pay attention to .NET code access security. Read MSDN documentation to see if the class, method(s) you're using requires full-trust or not. This may be an issue if your app is supposed to run in partial trust or less privileged trust environment.
System.Diagnostics.Process.GetProcesses("MACHINEHAME")