Службы Windows с Windows формы в том же процессе - PullRequest
6 голосов
/ 01 октября 2008

У меня есть приложение на c #, которое работает как служба Windows, контролирующая соединения с сокетами и другие вещи. Также есть еще одно приложение для создания форм Windows для управления и настройки этой службы (systray с start, stop, show form с параметрами конфигурации).

Я использую .net remoting для выполнения IPC, и это было нормально, но теперь я хочу показать реальный трафик и другие отчеты, и удаленное взаимодействие не будет соответствовать моим требованиям к производительности. Поэтому я хочу объединить оба приложения в одном.

Вот проблема:

Когда я запустил форму из службы Windows, ничего не произошло. Погуглив, я обнаружил, что должен щелкнуть правой кнопкой мыши службу, перейти в раздел «Вход в систему» ​​и установить флажок «Разрешить службе взаимодействовать с рабочим столом». Так как я не хочу просить моих пользователей сделать это, я снова набрал код в Google, чтобы установить эту опцию в regedit пользователя во время установки. Проблема в том, что даже при установке этой опции она не работает. Я должен открыть параметры входа службы (проверено), снять флажок и проверить еще раз.

Итак, как это решить? Как лучше всего использовать службу Windows с элементом управления systray в одном и том же процессе, доступную для любого пользователя, выполняющего вход?

ОБНОВЛЕНИЕ: Спасибо за комментарии, ребята. Я согласен, что лучше использовать IPC, и я знаю, что смешивать службы Windows и пользовательские интерфейсы плохо. Хотя я хочу знать, как это сделать.

Ответы [ 8 ]

18 голосов
/ 01 октября 2008

Два отдельных процесса, которые взаимодействуют с использованием выбранной вами технологии. Сервисы с пользовательским интерфейсом - это плохая идея . Не ходите по этой дороге - вы об этом пожалеете.

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

1 голос
/ 19 марта 2010

У меня есть решение в несколько шагов, это план

  1. мы не собираемся создавать проект службы с помощью формы Windows, вместо этого мы собираемся создать решение Visual Studio, которое содержит проект службы Windows, проект формы Windows и проект установки.

  2. Идея состоит в том, чтобы иметь базу данных, файл или все, что вам удобно для хранения данных, в которых вы будете хранить параметры, которые ваша служба Windows всегда будет использовать для запуска. Таким образом, ваша служба Windows и приложение Windows Form должны иметь возможность изменять и извлекать данные из нее.

  3. В основную форму вашего приложения Windows перетащите NotifyIcon на форму, на вкладку свойств, найдите и выберите изображение .ico (вы можете создать его в Visual Studio, но это еще одна тема, которую вы можете войти в Google или связаться со мной) Это будет отображаться в системном трее, когда вы запустите приложение, и основная форма активна или отображается, попробуйте его, запустите приложение.

  4. Добавьте их оба в качестве выходных данных в проекте установки решения. Чтобы добавить проект в проект установки, они должны быть в одном решении. Щелкните правой кнопкой мыши проект установки в обозревателе решений, выделите добавить, а затем выберите выходные данные проекта, добавьте службу Windows и выходные данные формы Windows, и вы увидите их в обозревателе решений в проекте установки.

  5. добавление службы Windows идет дальше, чем это, но это также другая тема google it

  6. Создание ярлыка для приложения Windows и добавление его в папку автозагрузки также является другой темой Google или свяжитесь со мной.

    ПРИМЕЧАНИЕ. Запрограммируйте вашу форму таким образом, чтобы кнопка закрытия не отображалась, а форма переходила в Me.visible = false, и двойной щелчок по значку на панели задач - единственный способ установить me.visible = true.that Таким образом, в любое время, когда компьютер запускается, приложение формы Windows также запускается, и для параметра visible сразу устанавливается значение false, но, поскольку у него есть уведомление с изображением значка, оно будет отображаться в системном трее, а двойной щелчок по нему делает форму видимой для редактирования Если вы сохраняете настройки для службы, она также запускается автоматически, поскольку вы установили бы ее при настройке службы в проекте установки. моя почта iamjavademon@gmail.com для лучшей иллюстрации с использованием снимков экрана и объяснения в полном объеме

1 голос
/ 24 ноября 2009

Я понял, как это сделать из этой статьи (нажмите ссылку "Изменить" в таблице методов).

string wmiPath = "Win32_Service.Name='" + SERVICE_NAME + "'";
using (ManagementObject service = new ManagementObject(wmiPath))
{
    object[] parameters = new object[11];
    parameters[5] = true;  // Enable desktop interaction
    service.InvokeMethod("Change", parameters);
}
1 голос
/ 23 июля 2009

Вот способ перепутать услуги и формы

http://www.codeproject.com/KB/system/SystemTrayIconInSvc.aspx

1 голос
/ 01 октября 2008

Я согласен с Грегом. Возможно, вы могли бы изучить другой механизм IPC. Возможно, используйте сокеты и свой собственный протокол. Или, если ваше приложение управления службами может управлять только службой на локальной машине, вы можете использовать именованные каналы (даже быстрее).

1 голос
/ 01 октября 2008

На практике вам не следует связывать свой сервис с пользовательским интерфейсом управления.

0 голосов
/ 08 января 2009

Основные проблемы с интерактивными услугами:

  • Безопасность - другой процесс может отправлять ему сообщения через насос сообщений, тем самым получая доступ к процессу SYSTEM / LOCAL.

  • Неполнота - интерактивный сервис никогда не видит сообщения оболочки, поэтому он не может взаимодействовать с иконками области уведомлений.

Мы регулярно используем TCP и UDP-соединения для передачи информации от сервисов к другим exe-файлам и, в некоторых случаях, MSMQ.

0 голосов
/ 21 октября 2008

Это очень просто - вам нужно создать один поток для выполнения событий приложения. Вот так (исходный код на C ++ с CLR, но вы можете сделать это на C #):

ref class RunWindow{
public:
    static void MakeWindow(Object^ data)
    {
        Application::EnableVisualStyles();
        Application::SetCompatibleTextRenderingDefault(false); 

        Application::Run(gcnew TMainForm());
    };
};

И создать тему в основном

int main(array<System::String ^> ^args)
{
    bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow");

    if (bService)
    {

        System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
        thread->Start();

        ServiceBase::Run(gcnew simpleWinService());
        Application::Exit();
    }
    else
    {
        Application::EnableVisualStyles();
        Application::SetCompatibleTextRenderingDefault(false); 

        // Create the main window and run it
        Application::Run(gcnew TMainForm());
    }

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...