Определить, открыта ли форма из другого проекта

Мое решение С# WinForm содержит несколько проектов, включая проект администратора с несколькими формами и проект пользователя с несколькими формами. Я хочу, чтобы мои пользовательские формы вели себя по-разному, когда открыты определенные формы администратора.

Как пользовательские формы могут определить, открыты ли формы администратора?

Все формы не имеют значения this.Text (все эти значения равны нулю).

Когда я перебираю все формы, указанные «FormCollection fc = Application.OpenForms», формы из другого проекта не отображаются; кажется, отображаются только формы из одного и того же проекта.

Кроме того, все формы администратора запускаются из одного файла .exe, а все формы пользователя запускаются из другого файла .exe.

Любая помощь приветствуется.


person Frederick    schedule 16.07.2010    source источник


Ответы (2)


Используйте класс Mutex для этой области.
Mutex — это Windows объект ядра, имеющий уникальный идентификатор компьютера Windows.

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;
        }
    }
}
person serhio    schedule 16.07.2010
comment
Добрый день Серхио, спасибо за ответ. Я реализовал ваше предложение, но у меня возникли проблемы с освобождением мьютекса. Я опубликовал новый вопрос с подробностями об этой проблеме. Если у вас есть минутка, я был бы признателен, если бы вы взглянули на него. Новый вопрос здесь: stackoverflow.com /questions/3275527/мьютекс-не-релиз - person Frederick; 18.07.2010
comment
@Frederik: Итак, интересно, каким было решение, вызывающее WaitOne (0) в дополнение или вместо OpenExisting? - person serhio; 19.07.2010
comment
Я все еще работаю над этим. Вчера я понял, что мой код страдает от слабости, когда при определенных условиях (условиях, которые я тестировал) открывается несколько копий формы администратора, одна поверх другой. Это вызвало множество исключений. Я опубликую свой код, как только он заработает. - person Frederick; 20.07.2010
comment
Кроме того, в Form2 метод Close() следует вызывать перед вызовом Exit(), иначе метод OnClosed в вашем коде не будет вызываться. - person Frederick; 20.07.2010
comment
@Serhio: я опубликовал свой окончательный рабочий код в качестве обновления к этому сообщению: stackoverflow.com/questions/3275527/mutex -не-релиз. В итоге я не использовал WaitOnce, а использовал только OpenExisting, убедившись, что закрыл все ссылки на именованный мьютекс. - person Frederick; 21.07.2010
comment
@ Фредерик: хорошая работа. Насчет вызова Клоуз мне кажется странным. Вы пытались вызвать base.OnClosing() в последней строке? - person serhio; 21.07.2010
comment
@Серхио, если честно, я не знаком с тем, что такое «база» и как ее использовать. Как мне было указано в других комментариях, использование OpenExisting создает ссылку на именованный мьютекс, который необходимо закрыть до того, как мьютекс умрет. Если я не закрою ссылку, то мьютекс будет жить, даже после выхода из формы администратора, и тогда мне нужно будет использовать WaitOne, чтобы увидеть, сигнализируется мьютекс или нет. - person Frederick; 21.07.2010
comment
Про Mutex понял, а вот с OnClosing проблема... Не стоит там вызывать Close. OnClosing — это переопределенная функция базового класса, которая генерирует событие Closing. Этот вызывается базовым классом (.NET Windows.Forms.Form) при закрытии формы. Итак, вызывая Close в OnClosing, вы делаете одно и то же дважды. - person serhio; 21.07.2010

Что вам нужно, так это способ межпроцессного взаимодействия.
Есть много способов добиться этого, большинство из них будет излишним для вашей ситуации.
Я считаю, что лучший способ в вашем случае - это иметь файл, процесс будет записывать, а другие процессы будут читать и делать выводы о состоянии процесса администратора.

person Itay Karo    schedule 16.07.2010
comment
Привет Итай. Спасибо за ответ. Мне нравится ваше предложение за его простоту; однако я беспокоюсь о безопасности, поскольку кто-то может легко изменить значение, хранящееся в файле. Знаете ли вы способ реализовать ваше предложение, когда файл защищен от манипуляций? - person Frederick; 18.07.2010
comment
Вы можете использовать олицетворение, чтобы записывать/читать файл от имени другого пользователя, который будет единственным пользователем с правами доступа к этому файлу. но это потребует добавления специального пользователя, который будет добавлен к машинам, на которых вы развертываете свою программу. Решение Mutex лучше :), но я не уверен, что описанное здесь использование будет работать. - person Itay Karo; 18.07.2010
comment
@Italy: Что заставляет вас сомневаться в представленном решении? - person serhio; 20.07.2010
comment
@serhio - Насколько я понимаю, если Form2 закрыт, мьютекс Form2 не существует, поэтому при запуске Mutex.OpenExisting("Form2") в form3 WaitHandleCannotBeOpenedException будет выброшено и будет ложно указывать, что form2IsOpen - person Itay Karo; 20.07.2010
comment
ага... должно быть form2IsOpen в false. Я бы починил этот. - person serhio; 20.07.2010
comment
Прочитайте ответ, предоставленный Крисом Тейлором в моем связанном вопросе (ссылка на этот вопрос показана выше в комментарии к ответу Серхио). Крис Тейлор делает хорошее замечание о том, как мьютекс ведет себя в ответ на первое открытие Form2 (форма «Администратор»), и как это влияет на OpenExisiting. - person Frederick; 20.07.2010