Каковы лучшие практики внедрения ОАК? (.СЕТЬ)

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

Теперь вопрос в том, как это реализовать в .NET? Я знаю, что только целые процессы или, возможно, некоторые экземпляры COM могут быть подняты, а не отдельные функции. Но это было именно то, что мне нужно. Какого пути я должен идти? Напишите два исполняемых файла, один с манифестом, а другой без; программно запускать тот же процесс, который был повышен во второй раз; использовать некоторые COM-вещи? Тогда у меня есть дополнительные привилегии, но как сказать другому процессу, что делать? Использовать удаленную платформу .NET(которая устарела/сложна?); реализовать мою собственную вещь IPC с помощью сокетов/труб/что угодно? Эта повышенная задача, возможно, потребуется спросить у пользователя что-то в середине процесса. И он должен быть отменен.

Там много сказано, как UAC работает внутри или как системные администраторы могут его настроить, но я не нашел ничего, что отвечало бы на эти основные вопросы.

Ответ 1

Кажется, у нас есть два разных вопроса:

  • Как мне обрабатывать операции, требующие повышенных привилегий?
  • Если я использую отдельный процесс, как я должен сказать другому процессу, что делать?

Здесь моя попытка ответить на них:

  • Похоже, что из этого SO-вопроса: Windows 7 и Vista UAC - запрограммировать запрос на повышение в С#, что решение такое, как вы предложили в своем вопросе (для запуска другого обрабатывать и запрашивать возвышение при запуске) - это "правильный ответ"
  • Что касается сообщения другому процессу, что делать, вот как я мог бы нанести ему удар:

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

Например, ваша программа должна остановить/запустить службу, я бы написал небольшую вспомогательную программу под названием servicecontroller (ну в действительности вы, вероятно, захотите использовать net), который принял аргументы командной строки, подобные этому:

servicecontroller stop MyCoolService
servicecontroller start MyCoolService

Эти аргументы будут созданы программой "Main" и пройдены после нажатия "ОК".

Есть несколько проблем с решением выше, хотя вы можете или не можете заботиться о нем:

  • Вы передаете аргументы в командной строке, которые можно легко понюхать
  • Вы ограничены длиной ProcessStartInfo.Argument + Путь к программе (из MSDN: длина аргументов, добавленных к длине полного пути к процессу должно быть меньше 2080.)
  • Получение информации, переданной вам, может быть немного сложной (если вам это нужно)

Немного больше googling раскрыл этот пост в блоге 'DevZest', который в основном рекомендует то, что я описал выше. Удачи!


EDIT На основании дополнительных вопросов, заданных в комментариях:

  • Рекомендуете ли вы запускать отдельный исполняемый файл или тот же исполняемый файл, когда вам нужно выполнить повышенные действия?
  • (я читаю между строками на этом) Как часто я должен предлагать пользователю эти действия?

Не зная точно, что вы здесь делаете, я беру его на себя:

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

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

Что касается примера текстового редактора, я бы сделал что-то подобное, как указано выше, когда пользователь дает вам проверку целевого каталога, чтобы увидеть, что у вас есть доступ на запись к этому местоположению, если не сообщить пользователю о том, что они сохраняются в местоположении который требует повышения, сохраните их работу в доступном для записи месте (ваша программа APPDATA, вероятно, является хорошим местом или даже TEMP), затем сработает процедура копирования, которая запрашивает повышение, если пользователь отменяет диалог UAC, убедитесь, что вы зафиксировали это отмена и удалите временный файл.

Я бы отговорил вас от продолжения процесса работы с повышенными рабочими местами, если вы обнаружите, что ваша программа должна запрашивать возвышение более чем несколько раз (Readas: 1 или 2 угловых случая) во время жизненного цикла программы, тогда я бы поставил под вопрос, почему это не был отмечен как всегда повышенный. Мне нравится следовать правилу "наименьшего удивления", когда я даю вам повышенные права. Я ожидаю, что вы выполните только действия, которые его запросили, а не продолжать перекачивать действия, требующие повышения по первому запросу.

Все, что сказано, ничего не мешает вам сделать выше, как только вы позволите некоторому процессу получить повышенные права, которые он может пригласить во всех своих приятелях. Исходя из вашего желания поддерживать повышенный процесс, почему бы не просто сохранить текущее состояние программы и перезапустить программу с повышенными привилегиями и восстановить состояние? Это, на мой взгляд, совпадает с тем, что рабочий процесс существует в постоянно повышенном состоянии.

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