PostMessage в службе (daemon) вообще не работает?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

PostMessage в службе (daemon) вообще не работает?

Сообщение jsa »

Всем здравия.
На основе работающего приложения делаю службу.
Наткнулся на проблему,
PostMessage(Handle, Msg_createFILES, 2, 0);
(из многопоточной процедуры отправляется в основной поток сообщение для запуска процедуры которая взаимодествует с файловой системой.)
компяилятор ругается на Handle, я так понимаю у службы нет заголовка.
Получается, что такого типа сообщения служба сама себе или в другое приложение послать не может?
Последний раз редактировалось jsa 20.04.2023 05:27:58, всего редактировалось 1 раз.
delphius
постоялец
Сообщения: 131
Зарегистрирован: 18.03.2020 12:40:11

Сообщение delphius »

А почему не PostThreadMessage?

Код: Выделить всё

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.
Создается константа `Msg_createFILES` для определения пользовательского сообщения. Затем определяется глобальная переменная `MainThreadId` для хранения идентификатора основного потока. Процедура `HandleMessage` используется для обработки сообщений в основном потоке. Она проверяет наличие сообщений в очереди сообщений с помощью функции `PeekMessage` и обрабатывает пользовательское сообщение `Msg_createFILES`, выводя соответствующее сообщение в консоль.

Далее определяется подкласс `TMyThread` класса `TThread` для выполнения кода во вспомогательном потоке. Метод `Execute` этого класса переопределяется для отправки сообщения из вспомогательного потока в основной с помощью функции `PostThreadMessage`.

В главной части программы получается идентификатор основного потока с помощью функции `GetCurrentThreadId`. Затем создается экземпляр класса `TMyThread` и запускается с помощью свойства `Start`. В бесконечном цикле вызывается процедура `HandleMessage` для обработки сообщений в основном потоке.
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Думал что ситуация разрешится, через нахождение Handle процесса другим способом.
Получается, что такого типа идентификатор есть только у визуальных компонент.

Спасибо большое.
Буду разбираться.
Аватара пользователя
Sharfik
энтузиаст
Сообщения: 836
Зарегистрирован: 20.07.2013 01:04:30

Сообщение Sharfik »

В чем плюсы службы?
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Sharfik писал(а):В чем плюсы службы?
Служба/сервис/демон это "часть системы" и их код может быть очень компактным + работать там где иначе пришлось бы спуститься на "уровень драйвера" . Что до Handle то он действительно связан с оком, но никто не мешает юзать Handle "чужого окна" ( например через Screen.Monitors[0].Handle (хотя я конкретно это фокус в службе не использовал ) )
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Sharfik писал(а):В чем плюсы службы?
Служба в отличии от обычной программы запускается не в конкретной сессии пользователя, а на уровне системы.
Т.е. при перезапуске сервера, админу не нужно входить в сессию, чтобы запустить (или автоматом запустился) сервис.
И у службы нет визуального интерфейса.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

jsa писал(а):И у службы нет визуального интерфейса.
Если его не делать.
В своё время на делфи делал службы с визуальным интерфейсом, для удобства настроек.
Аватара пользователя
Sharfik
энтузиаст
Сообщения: 836
Зарегистрирован: 20.07.2013 01:04:30

Сообщение Sharfik »

Я тут писал про клиент-серверное приложение, в соседних темах. Вот думаю серверную часть в последствии пытаться сделать службой или оставить иконкой в трее. Про то, что может быть запущен не тот пользователь, под которым сервер должен запускаться это конечно аргумент в пользу службы. Службу без админов не установить, а приложение можно и без них скопировать.
А служба сама может пойти на ребут? Если зависнет на удаленной машине, то автоматические средства перезапуска есть? Или надо писать параллельный мониторинг?
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 564
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

Sharfik писал(а):А служба сама может пойти на ребут? Если зависнет на удаленной машине, то автоматические средства перезапуска есть? Или надо писать параллельный мониторинг?
Как минимум в Linux - да, такие средства есть. Systemd умеет рестарт по событиям (краш, ошибка, не отвечает и т.д.)
В Windows, насколько я помню, тоже есть (св-ва службы->восстановление)
Ответить