Вызов внешней программы для запуска от имени обычного пользователя из требуемой программы администратора

Моя программа Visual Basic будет копировать файлы в папку с программными файлами, поэтому я должен использовать привилегии requiredAdministrator, так как asInvoker не позволяет писать в папку с программными файлами.

После того, как я скопирую файлы, я вызываю скрипт AutoIt, автоматизирующий настройку файлов во внешней программе (для этого скрипт вызывает внешнюю программу для запуска автоматизации). Программа, которая создает и копирует файлы в «конец», работает нормально. Сценарий, вызывающий программу "конец" и выполняющий автоматическую настройку, также работает.

Когда я комбинирую 2, «конечная» программа (которую я не писал и не имею исходного кода) ведет себя хаотично при запуске от имени администратора (не читает базу данных или необходимые файлы возвращают ошибку и завершает работу). Так что запускать от имени администратора не вариант. Но поскольку моя программа должна работать от имени администратора, похоже, что она передает те же привилегии сценарию AutoIt, который также вызывает «конечную» программу от имени администратора. Это также происходит, если я вызываю программу «конец» из своего приложения вместо сценария AutoIt.

Есть ли способ понизить мое приложение от администратора до обычного пользователя после того, как оно скопирует файлы, прямо перед вызовом сценария AutoIt или «конечной» программы, чтобы «конечная» программа не запускалась как администратор или параметр, который специально заставляет приложение вызывать внешнюю программу как обычный пользователь?

Я использую Process.start("autoitscript.exe") для вызова. Или любой другой обходной путь, который не включает скрипт AutoIt, вызывающий «конечную» программу и мое приложение, потому что это работает, но не так, как я намеревался.


person GHoStyaiRo    schedule 29.04.2016    source источник


Ответы (1)


Это сложная задача для выполнения, но как насчет этого:

  1. Запустите ваше приложение asInvoker, не показывайте никаких окон и проверьте, работает ли оно с повышенными привилегиями, используя этот код:

    Public Shared Function IsAdministrator() As Boolean
        Return (New WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator)
    End Function
    

    Если он не работает с повышенными привилегиями, запустите невидимый экземпляр cmd, где вы перенаправляете стандартный ввод.

  2. Получите PID процесса cmd и теперь запустите новый экземпляр вашего приложения с повышенными привилегиями (это можно сделать, установив StartInfo.Verb = "runas") и передайте PID в качестве параметра командной строки.

  3. Теперь ваш новый экземпляр приложения запускается, и IsAdministrator() должно возвращать True.

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

  4. В конце, когда вы хотите запустить приложение autoitscript.exe, вы создаете переменную процесса и назначаете ей Process.GetProcessById(<your PID Integer here>).

    Например:

    Dim cmdProcess As Process = Process.GetProcessById(cmdPID)
    
  5. Теперь, когда у вас снова есть контроль над экземпляром cmd, вам просто нужно писать в его стандартный ввод (эта статья немного описывает, как это работает).

    Вы хотите написать две строчки. Первый — запустить другое приложение:

    autoitscript.exe
    

    а второй — закрыть экземпляр cmd:

    exit
    

Если что-то неясно, просто дайте мне знать.

person Visual Vincent    schedule 29.04.2016