среда, 10 июня 2026 г.

Пример кода на Lazarus 4.6, dglOpenGL, SDL2 под Debian 13 . Инициализация SDL2, dglOpenGL.

Программа реализует пример инициализации SDL2 для создания окна и обработки событий окна на изменения размеров окна, закрытия окна по нажатию клавиши ESC. Инициализация dglOpenGL.

Рисунок 1. Демонстрация работы программы. Вращающийся треугольник.

Код проекта:

program ogl_p4;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes,
  sysutils,
  sdl2lib,
  dglOpenGL;
const
  WINDOW_WIDTH  = 800;
  WINDOW_HEIGHT = 600;

var
  Window: PSDL_Window = nil;
  GLContext: TSDL_GLContext = nil;
  Event: TSDL_Event;
  Running: Boolean = True;
  RotateAngle: Single = 0.0;

procedure InitSystem;
begin
     // Загружаем SDL2 library из системных путей Debian 13 напрямую
     if Not SDL2LIB_Initialize(SDL_LibName) then
     begin
       raise Exception.Create('Не удалось динамически загрузить libSDL2.so через SDL2LIB_Initialize');
     end;

  // Инициализируем видеосистему SDL2
  if SDL_Init( SDL_INIT_VIDEO ) < 0 then
  begin
    WriteLn('Ошибка инициализации SDL2: ', SDL_GetError());
    Halt(1);
  end;

  // Настраиваем параметры OpenGL перед созданием окна
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

  // Создаем окно через SDL2
  Window := SDL_CreateWindow(
    'SDL2 + dglOpenGL + Lazarus (Debian 13)',
    SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
    WINDOW_WIDTH, WINDOW_HEIGHT,
    SDL_WINDOW_OPENGL or SDL_WINDOW_SHOWN
    or SDL_WINDOW_RESIZABLE
  );

  if Window = nil then
    raise Exception.Create('Не удалось создать окно SDL2');

  // Создаем контекст OpenGL
  GLContext := SDL_GL_CreateContext(Window);
  if GLContext = nil then
    raise Exception.Create('Не удалось создать контекст OpenGL');

  // Загружаем внутренние указатели OpenGL (dglOpenGL подхватит контекст SDL2)
  if not InitOpenGL then
    raise Exception.Create('Не удалось инициализировать dglOpenGL через контекст SDL2');

  // Читаем расширения
  ReadExtensions;
  // Строку ReadImplementationProperties; лучше убрать, в некоторых версиях dglOpenGL под Linux она падает
  ReadImplementationProperties;

  // Базовая настройка сцены (Матрицы и проекция)
  glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0, WINDOW_WIDTH / WINDOW_HEIGHT, 0.1, 100.0);
  glMatrixMode(GL_MODELVIEW);
  glClearColor(0.1, 0.1, 0.15, 1.0);
end;

procedure HandleResize(Width, Height: Integer);
begin
  // Защита от деления на ноль, если окно свернули
  if Height = 0 then Height := 1;

  // Обновляем область вывода OpenGL на весь экран окна
  glViewport(0, 0, Width, Height);

  // Переключаемся на матрицу проекции для ее обновления
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  // Задаем перспективную или ортогональную проекцию
  // Пример для Перспективы (3D): fov = 45 градусов, ближний отсекатель = 0.1, дальний = 100.0
  gluPerspective(45.0, Width / Height, 0.1, 100.0);

  // Возвращаем матрицу модели для обычного рендеринга объектов
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
end;

procedure HandleEvents;
begin
  // Обрабатываем очередь сообщений SDL2
  while SDL_PollEvent(@Event) <> 0 do
  begin
    case Event.type_ of
      // Событие закрытия окна
      SDL_QUITEV:
        Running := False;
      SDL_WINDOWEVENT:
      begin
           // Проверяем конкретный подтип события
          case Event.window.event of
            SDL_WINDOWEVENT_RESIZED,SDL_WINDOWEVENT_SIZE_CHANGED:
            begin
              // Извлекаем новые параметры ширины и высоты из события
              // и обновляем матрицы
              HandleResize(Event.window.data1, Event.window.data2);
            end;
          end;
      end;
      SDL_KEYDOWN:
        begin
          if Event.key.keysym.sym = SDLK_ESCAPE then
            Running := False;
        end;
    end;
  end;
end;

procedure UpdateFrame;
begin
  RotateAngle := RotateAngle + 0.5;
  if RotateAngle >= 360.0 then
    RotateAngle := RotateAngle - 360.0;
end;

procedure RenderFrame;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  // Отодвигаем камеру назад на 3 единицы по оси Z (объект окажется перед камерой)
  glTranslatef(0.0, 0.0, -3.0);

  glRotatef(RotateAngle, 0.0, 0.0, 1.0);

  // Рисуем простой треугольник
  glBegin(GL_TRIANGLES);
    glColor3f(1.0, 0.0, 0.0); glVertex2f(0.0, 1.0);
    glColor3f(0.0, 1.0, 0.0); glVertex2f(-1.0, -1.0);
    glColor3f(0.0, 0.0, 1.0); glVertex2f(1.0, -1.0);
  glEnd();

  SDL_GL_SwapWindow(Window);
end;

procedure CleanUp;
begin
  if GLContext <> nil then
    SDL_GL_DeleteContext(GLContext);

  if Window <> nil then
    SDL_DestroyWindow(Window);

  SDL_Quit();
end;

begin
  try
    InitSystem;

    // Главный цикл программы
    while Running do
    begin
      HandleEvents;
      UpdateFrame;
      RenderFrame;
      SDL_Delay(16);
    end;

  except
    on E: Exception do
      Writeln('Ошибка: ', E.Message);
  end;

  CleanUp;
end.

 

воскресенье, 24 мая 2026 г.

Как удалить pdf24 с удаленного компьютера в локальной сети при помощи PsExec

Нашёл способ удаления программы pdf24 на удалённом компьютере в локальной сети. Команду удаления на удалённом компьютере будем запускать при помощи программы PsExec.exe. Если инсталлятор pdf24 создан на базе msi пакета, то удаление проводится при помощи программы MsiExec.exe, которая присутствует по-умолчанию в Windows 10 x64. Если инсталлятор pdf24 создан в виде exe пакета, то удаление сводится к запуска специального деинсталлятора unins000.exe, который находися в папке, куда установлена программа pdf24, по-умолчанию это путь (C:\Program Files\PDF24\unins000.exe). Сразу скажу, что на удаленном компьютере вы должны быть администратором, то есть ваша учётная запись должна находится в группе Администраторы.

Если установщик pdf24 создан в виде msi пакета, то чтобы удалить pdf24 нам нужно узнать идентификатор продукта msi (product_guid) pdf24. Идентифактор продукта msi для pdf24 можно посмотреть в реестре Windows 10. На всех компьютерах, где был установлен msi пакет pdf24 версии 11.23.0 будет GUID {092211C0-0A7B-4D36-A70D-C6DD8236533E}. В реестре его можно посмотреть по следующему пути:

Компьютер\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{092211C0-0A7B-4D36-A70D-C6DD8236533E}

В этой ветке найдите параметр UninstallString и там будет значение MsiExec.exe /I{092211C0-0A7B-4D36-A70D-C6DD8236533E}.

Взяв этот GUID сформируем команду удаления этого продукта с компьютера: "MsiExec.exe" /x {092211C0-0A7B-4D36-A70D-C6DD8236533E} /qn /norestart

/x – параметр удаления продукта

{092211C0-0A7B-4D36-A70D-C6DD8236533E} – GUID продукта для pdf24 версии 11.23.0

/qn – не выводить диалоги (окна) выбора ответа на вопрос (тихий режим удаления).

/norestart – не перезагружаем компьютер, если требуется.

Теперь применим эту команду удаления для pdf 24 на удалённый компьютер в локальной сети.

PsExec.exe \\pc01 -i -s -h -accepteula -nobanner "MsiExec.exe" /x {092211C0-0A7B-4D36-A70D-C6DD8236533E} /qn /norestart

\\pc01 – имя удалённого компьютера

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

s – права запуска учётной записи SYSTEM

h – запуск процесса с повышенными правами

accepteula - принимаем лицензионное соглашение, чтобы всплывающего окна не появилось

nobanner – скроем окно о правах

В том случае, если инсталлятор pdf24 в виде exe пакета, то команда удаления на локальном компьютере будет выглядить так: "C:\Program Files\PDF24\unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART

/VERYSILENT – скрываем окно удаления и всё, что сним свзязано

/SUPPRESSMSGBOXES – закрываем все всплывающие сообщение в процессе удаления

/NORESTART - не перезагружаем компьютер, если требуется.

Теперь посмотрим команду удаления pdf24 программы в виде exe пакета на удалённом компьютере: PsExec.exe \\pc01 -i -h -accepteula -nobanner "C:\Program Files (x86)\PDF24\unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART


На этом все. Данные команды работают. Сам проверил.