Вопрос

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

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

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

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

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

Вот способ смешивания Сервисов и Форм

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

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

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. мы не собираемся создавать сервисный проект с Windows form, вместо этого мы собираемся создать решение Visual Studio, которое содержит сервисный проект Windows, проект Windows form и проект установки.

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

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

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

  5. добавление службы Windows выходит за рамки этого, но это тоже другая тема, погуглите

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

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

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

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

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

И создайте поток в main

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;
}

Основными проблемами, связанными с интерактивными сервисами, являются:

  • Безопасность - другой процесс может отправлять ему сообщения через свою перекачку сообщений, тем самым получая доступ к СИСТЕМНОМУ / ЛОКАЛЬНОМУ процессу.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top