Задать вопрос
@ImagineTables

Архитектура для приложения, повышающего привилегии?

Есть приложение, которое выполняет файловые операции. В основном над юзерскими файлами, но иногда — над системными. Для выполнения над системными требуется повышение прав. Я почитал, как устроен FAR, который делает именно это. Пишут (не знаю, правда или нет), что он показывает диалог о необходимости повышения прав, а затем создаёт новый процесс самого себя от админа. Если юзер нажал «Да» в UAC, старый процесс завершается и происходит клонирование. Для FAR'а это очень удобно, поскольку всё его состояние — по сути, только два адреса: для левой и правой панелей. Моё же приложение имеет сложное состояние, да ещё и с подключаемыми модулями, и мне вариант с клонированием не нравится.

Остаётся вариант с хелперным дочерним процессом, запускаемым из-под админа, который и возьмёт на себя файловые операции.

Архитектура мне видится такой:

1. Файловые операции описаны интерфейсом (условно, IFileOps).
2. Этот интерфейс IFileOps имплементируется неким объектом внутри главного процесса (условно, InProcFileOps) для юзерских файлов. Если юзер не лезет в системные папки, он никогда не видит UAC.
3. Этот же интерфейс IFileOps имплементируется в хелперном процессе (условно, объектом LocalFileOps, где слово Local означает «внешний процесс»).
4. Когда любой метод InProcFileOps получает ERROR_ACCESS_DENIED, главный процесс создаёт хелперный процесс от админа, юзер видит UAC, нажимает «Да», главный процесс заменяет ссылку на InProcFileOps ссылкой на LocalFileOps, дальше операции идут через него, юзер видит UAC один раз. Всё как в FAR.
5. Вызывающая сторона НЕ ЗНАЕТ, кто в данный момент имплементирует IFileOps.
6. LocalFileOps не имплементирует IFileOps с нуля, а создаёт в своём адресном пространстве экземпляр InProcFileOps, затем делегирует ему, обеспечивая правами.
7. Ясен пень, данные при вызове методов IFileOps хелперного процесса из главного процесса нужно как-то маршалить из-за межпроцессной границы.

Вопросы следующие:

1. Не упускаю ли я хорошие альтернативные подходы?
2. Если оставить этот подход, годная ли описанная выше архитектура?
3. И если да, на чём это сделать?

Можно взять COM. Описать IFileOps на IDL. Сделать два кокласса: InProcFileOps в dll и LocalFileOps в .exe. Local-кокласс создавал бы инстанс InProcFileOps и вызывал его методы 1:1. Затем в коде основного процесса написать #import "FileOps.tlb", а весь бойлерплейт по обращению к внешнему процессу, насколько я помню, вроде сам должен после этого сгенерироваться.

Но, товарищи, что-то не уверен я, что в 2026 году стоит писать на COM'е. Может, есть какие-то библиотеки/инструменты, допустим, на пайпах? Главное, чтобы invoke самому не писать. А, ну ещё скорость важна, конечно. Допустим, файлов в папке будет очень много. И для каждого надо что-то узнать и это несколько вызовов разных методов из IFileOps. И всё это, наверно, было бы лучше автоматически упаковывать в один batch… или нет?

Буду благодарен за любые соображения.
  • Вопрос задан
  • 17 просмотров
Подписаться 1 Средний Комментировать
Помогут разобраться в теме Все курсы
  • Нетология
    Инженер по автоматизации
    13 месяцев
    Далее
  • Бруноям
    Системный администратор
    6 месяцев
    Далее
  • Stepik
    Zabbix 6. Мониторинг IT инфраструктуры предприятия
    1 месяц
    Далее
Пригласить эксперта
Ответы на вопрос 2
VoidVolker
@VoidVolker Куратор тега Windows
Dark side eye. А у нас печеньки! А у вас?
Просто запускать приложение сразу от имени администратора и не заниматься бесполезным усложнением. Не, если скучно и хочется приключений — то вперёд, никаких проблем. Передать состояние между потоками можно через обычный сокет, файл, да даже просто напрямик блок данных передать через чтение/запись в память процесса.
Ответ написан
Комментировать
opium
@opium
Просто люблю качественно работать
а зачем городить с нуля? то что ты описал в пп 1-6 — это буквально COM Elevation Moniker, готовый Windows-примитив ровно под твой сценарий: CoGetObject с монитором вида Elevation:Administrator!new:{CLSID} сам поднимает elevated-инстанс через UAC, без клонирования процесса и без ручного маршалинга. Не хочешь COM — тот же движок без обвязки: MIDL + ncalrpc, proxy/stub генерятся сами, транспорт локальный. И не мельчи интерфейс, батчи вызовы на список путей — на каталоге с кучей файлов голый RPC на файл сожрёт всю экономию.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы