views:

73

answers:

2

My c# WinForm solution contains several projects including an Admin project with several forms and a User project with several forms. I want my user forms to behave differently when specific admin forms are open.

How can the user forms tell when admin forms are open?

All forms have no 'this.Text' value (all these values are null).

When I loop through all forms identified by 'FormCollection fc = Application.OpenForms', it does not show the forms from the other project; it seems to only show the forms from the same project.

Also, all the admin forms run from one .exe file and all the user forms run from another .exe file.

Any help is appreciated.

A: 

What you need is a way of Inter Process Communication.
There are many ways to achieve this most of the will be overkill for your situation.
I this the best way is your case is to have a file that the admin process will write to and the other processes will read from and infer the state of the admin process.

Itay
Hello Itay. Thank you for responding. I like your suggestion for it's simplicity; however, I am concerned about security in that it may be easy for someone to change the value stored in the file. Do you know of a way to implement your suggestion where the file is protected from being manipulated?
Frederick
You can use impersonation in order to write/read the file as another user that will be the only user with permissions on this file. but it will require adding a special user to be added to the machines on which you deploy your program. The Mutex solution is better :) but I am not sure the useage as was written here will work.
Itay
@Italy: What makes you doubt the presented solution?
serhio
@serhio - To my understanding if Form2 is closed the mutex `Form2` does not exists so while running `Mutex.OpenExisting("Form2")` on form3 `WaitHandleCannotBeOpenedException` will be thrown and will falsely indicate that `form2IsOpen`
Itay
yah... there should be form2IsOpen in false. I'd fix this one.
serhio
Read the answer provided by Chris Taylor in my related question (a link to that question is shown above in a comment to Serhio's answer). Chris Taylor makes a good point about how the mutex behaves in response to the first time Form2 (the 'Admin' form) is opened and it's implication on OpenExisiting.
Frederick
+1  A: 

Use Mutex class for that scope.
Mutex is a Windows kernel object that has an unique identifier for a Windows computer.

public class Form2 : Form
{
    Mutex m;
    protected override void OnShown(EventArgs e)
    {
        base.OnShown(e);
        m = new Mutex(true, "Form2");
    }

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        m.ReleaseMutex();
    }
}

public class Form3 : Form
{
    bool form2IsOpen;
    public Form3()
    {
        try
        {
            Mutex.OpenExisting("Form2");
            form2IsOpen = true;
        }
        catch (WaitHandleCannotBeOpenedException ex)
        {
            form2IsOpen = false;
        }
    }
}
serhio
Hello Serhio, thank you for your response. I implemented your suggestion but I am having trouble getting the mutex to release. I have posted a new question with details about this problem. If you have a moment, I'd appreciate you taking a look at it.The new question is here: http://stackoverflow.com/questions/3275527/mutex-not-releasing
Frederick
@Frederik: So, wondering, what was the solution, calling WaitOne(0) in addition or instead of OpenExisting?
serhio
I am still working on it. Yesterday I realized my code suffered from the weakness where, under certain conditions (the conditions I was testing), multiple copies of the Admin form are opened, one on top of the other. This caused many exceptions to be thrown. I will post my code once it is working.
Frederick
Also, on Form2, Close() should be called before calling Exit(), or else the OnClosed method in your code will not be called.
Frederick
@Serhio: I posted my final, working code as an update to this post: http://stackoverflow.com/questions/3275527/mutex-not-releasing. I ended up not using WaitOnce and only using OpenExisting by insuring that I closed all references to the named mutex.
Frederick
@Frederick: good job. About calling Close, seems strange to me. Did you try calling base.OnClosing() the last line?
serhio
@Serhio, to be honest, I am not familiar with what 'base' is or how to use it. As was pointed out to me in other comments, using OpenExisting creates a reference to the named mutex that needs to be closed before the mutex dies. If I don't close the reference, then the mutex lives on, even after exiting the Admin form, and then I would need to use WaitOne to see if the mutex is signaled or not.
Frederick
I understood about Mutex, but with OnClosing is the problem... You should not call Close there. OnClosing is a overriden base class function, that emits the Closing event. This one is called by the base class (.NET Windows.Forms.Form) when the form is closed. So, calling Close in OnClosing yo do the same thing twice.
serhio