PostMessage в службе (daemon) вообще не работает?
Модератор: Модераторы
PostMessage в службе (daemon) вообще не работает?
Всем здравия.
На основе работающего приложения делаю службу.
Наткнулся на проблему,
PostMessage(Handle, Msg_createFILES, 2, 0);
(из многопоточной процедуры отправляется в основной поток сообщение для запуска процедуры которая взаимодествует с файловой системой.)
компяилятор ругается на Handle, я так понимаю у службы нет заголовка.
Получается, что такого типа сообщения служба сама себе или в другое приложение послать не может?
На основе работающего приложения делаю службу.
Наткнулся на проблему,
PostMessage(Handle, Msg_createFILES, 2, 0);
(из многопоточной процедуры отправляется в основной поток сообщение для запуска процедуры которая взаимодествует с файловой системой.)
компяилятор ругается на Handle, я так понимаю у службы нет заголовка.
Получается, что такого типа сообщения служба сама себе или в другое приложение послать не может?
Последний раз редактировалось jsa 20.04.2023 05:27:58, всего редактировалось 1 раз.
А почему не PostThreadMessage?
Создается константа `Msg_createFILES` для определения пользовательского сообщения. Затем определяется глобальная переменная `MainThreadId` для хранения идентификатора основного потока. Процедура `HandleMessage` используется для обработки сообщений в основном потоке. Она проверяет наличие сообщений в очереди сообщений с помощью функции `PeekMessage` и обрабатывает пользовательское сообщение `Msg_createFILES`, выводя соответствующее сообщение в консоль.
Далее определяется подкласс `TMyThread` класса `TThread` для выполнения кода во вспомогательном потоке. Метод `Execute` этого класса переопределяется для отправки сообщения из вспомогательного потока в основной с помощью функции `PostThreadMessage`.
В главной части программы получается идентификатор основного потока с помощью функции `GetCurrentThreadId`. Затем создается экземпляр класса `TMyThread` и запускается с помощью свойства `Start`. В бесконечном цикле вызывается процедура `HandleMessage` для обработки сообщений в основном потоке.
Код: Выделить всё
program ThreadMessage;
uses
Windows, Classes;
const
// Определение константы для пользовательского сообщения
Msg_createFILES = WM_USER + 1;
var
// Глобальная переменная для хранения идентификатора основного потока
MainThreadId: DWORD;
// Процедура для обработки сообщений в основном потоке
procedure HandleMessage;
var
Msg: TMsg;
begin
// Проверка наличия сообщений в очереди сообщений
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
// Обработка пользовательского сообщения Msg_createFILES
if Msg.message = Msg_createFILES then
begin
WriteLn('Received message in main thread: ', Msg.wParam);
end;
// Обработка других сообщений
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
// Определение подкласса TThread для выполнения кода во вспомогательном потоке
type
TMyThread = class(TThread)
protected
// Переопределение метода Execute для выполнения кода во вспомогательном потоке
procedure Execute; override;
end;
// Реализация метода Execute для отправки сообщения из вспомогательного потока в основной
procedure TMyThread.Execute;
begin
WriteLn('Sending message from secondary thread');
PostThreadMessage(MainThreadId, Msg_createFILES, 2, 0);
end;
begin
// Получение идентификатора основного потока
MainThreadId := GetCurrentThreadId;
// Создание и запуск вспомогательного потока с помощью класса TMyThread
with TMyThread.Create(True) do
begin
FreeOnTerminate := True;
Start;
end;
// Бесконечный цикл для обработки сообщений в основном потоке
while True do
HandleMessage;
end.Далее определяется подкласс `TMyThread` класса `TThread` для выполнения кода во вспомогательном потоке. Метод `Execute` этого класса переопределяется для отправки сообщения из вспомогательного потока в основной с помощью функции `PostThreadMessage`.
В главной части программы получается идентификатор основного потока с помощью функции `GetCurrentThreadId`. Затем создается экземпляр класса `TMyThread` и запускается с помощью свойства `Start`. В бесконечном цикле вызывается процедура `HandleMessage` для обработки сообщений в основном потоке.
Думал что ситуация разрешится, через нахождение Handle процесса другим способом.
Получается, что такого типа идентификатор есть только у визуальных компонент.
Спасибо большое.
Буду разбираться.
Получается, что такого типа идентификатор есть только у визуальных компонент.
Спасибо большое.
Буду разбираться.
В чем плюсы службы?
Служба/сервис/демон это "часть системы" и их код может быть очень компактным + работать там где иначе пришлось бы спуститься на "уровень драйвера" . Что до Handle то он действительно связан с оком, но никто не мешает юзать Handle "чужого окна" ( например через Screen.Monitors[0].Handle (хотя я конкретно это фокус в службе не использовал ) )Sharfik писал(а):В чем плюсы службы?
Служба в отличии от обычной программы запускается не в конкретной сессии пользователя, а на уровне системы.Sharfik писал(а):В чем плюсы службы?
Т.е. при перезапуске сервера, админу не нужно входить в сессию, чтобы запустить (или автоматом запустился) сервис.
И у службы нет визуального интерфейса.
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
Если его не делать.jsa писал(а):И у службы нет визуального интерфейса.
В своё время на делфи делал службы с визуальным интерфейсом, для удобства настроек.
Я тут писал про клиент-серверное приложение, в соседних темах. Вот думаю серверную часть в последствии пытаться сделать службой или оставить иконкой в трее. Про то, что может быть запущен не тот пользователь, под которым сервер должен запускаться это конечно аргумент в пользу службы. Службу без админов не установить, а приложение можно и без них скопировать.
А служба сама может пойти на ребут? Если зависнет на удаленной машине, то автоматические средства перезапуска есть? Или надо писать параллельный мониторинг?
А служба сама может пойти на ребут? Если зависнет на удаленной машине, то автоматические средства перезапуска есть? Или надо писать параллельный мониторинг?
Как минимум в Linux - да, такие средства есть. Systemd умеет рестарт по событиям (краш, ошибка, не отвечает и т.д.)Sharfik писал(а):А служба сама может пойти на ребут? Если зависнет на удаленной машине, то автоматические средства перезапуска есть? Или надо писать параллельный мониторинг?
В Windows, насколько я помню, тоже есть (св-ва службы->восстановление)
