views:

120

answers:

3

I'm developing a long running process that hosts remoting objects. Due to design restrictions, I cannot use a Windows Service so the process is a background Forms application. I also cannot use WPF because we are restricted to .Net 2.0. In any case, since there is no guarantee that the background process is running, I want to be able to set a system wide flag from the process that I can check from another.

I read up and tried using Mutex's, but there doesn't seem to be a way to determine if a Mutex exists without creating it if it doesn't exist already(unless I'm missing something, which is always possible).

Ideally, a system wide variable with it's lifetime determined by the long running application would be ideal, not only to signal if it is running or not, but perhaps also to store primitive state data (like a simple integer enumeration).

Can anyone suggest a good way to accomplish this?

+1  A: 

Yes, use the Mutex class. You'll want the Mutex(bool, string, out bool) constructor, the last "createdNew" argument tells you if the mutex wasn't created yet. Prefix the name of the mutex with "global\" if you want to be able to detect that any version of the program is running in any session (including services and remote logins).

Hans Passant
I tried this approach. The problem is the second application will create the mutex if it doesn't exist already and it's lifetime is then controlled by that thread. This is not correct, the lifetime should only be controlled by the long running host application. I'm looking now at adding a Mutex Rights in the long running app and attempting to OpenExitsting. This should cause an exception in the second app...
Jason
You'll need to make it static so its lifetime is controlled by the process (AppDomain, really). Not of the host process, of the helper process.
Hans Passant
A: 

So using access control on the mutex seems to be the answer. Here is what I did:

On the long running process

        Dim MutextWasCreated As Boolean

        ' Create a security rule for the mutex so other threads cannot take ownership
        Dim MutexSec As New MutexSecurity
        Dim rule As New MutexAccessRule(Environment.UserDomainName & "\" & Environment.UserName, MutexRights.TakeOwnership, AccessControlType.Deny)

        MutexSec.AddAccessRule(rule)

        App_Mutex = New Mutex(True, "Global\MyMutexName}", MutextWasCreated, MutexSec)
        App_Mutex.WaitOne(-1, True)

Then, on the client app, use the following to attempt to open the mutex:

            Dim HostIsRunning As Boolean

        Try
            Mutex.OpenExisting("Global\MyMutexName", AccessControl.MutexRights.TakeOwnership)
        Catch ex As Exception
            If TypeOf ex Is UnauthorizedAccessException Then
                ' The mutex is created by the host to dissalow other threads from taking ownership. If we get this exception, we know the mutext has been created, thus the app is running.
                HostIsRunning = True
            ElseIf TypeOf ex Is WaitHandleCannotBeOpenedException Then
                HostIsRunning = False
            Else
                Throw ex
            End If
        End Try
Jason
A: 

from your main process expose with remoting samething as

MyProcessInfo : MarshalByRef { bool IsRunning() { return true; } }

if the remote calls throws the exception "cannot find the service MyProcessInfo.rem" (i don't remember the exact words) the process is not active and if you want you can return same info as your simple integer enumeration

kk