Запросите права администратора для приложения для какой-либо операции (без прав администратора на полный рабочий день)

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

Является ли это возможным?

PS Я знаю о манифесте и requiredExecutionLevel, но это не очень хорошее решение. Я хочу, чтобы у приложения были права администратора в течение некоторого периода времени не всегда.

2 ответа

Решение

Это невозможно, пока вы не начнете новый процесс.

Вы можете сделать это с:

var psi = new ProcessStartInfo();
psi.FileName = @"yourExe";
psi.Verb = "runas";

Process.Start(psi);

Вы можете запустить то же приложение, что и в данный момент, и передать параметр switch, чтобы проблема знала, что ему нужно только выполнить определенное действие.

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

using (ImpersonationManager impersonationManager = new ImpersonationManager())
{
    impersonationManager.Impersonate(Settings.Default.MediaAccessDomain, 
        Settings.Default.MediaAccessUserName, Settings.Default.MediaAccessPassword);
    // Perform restricted action as other user with higher permissions here
}

Обратите внимание, что это ImpersonationManager класс это пользовательский класс, поэтому вы не найдете его в MSDN, он просто использует SafeTokenHandle и другой код со связанной страницы:

private SafeTokenHandle safeTokenHandle;
private WindowsImpersonationContext impersonationContext;

const int LOGON32_LOGON_NEW_CREDENTIALS = 9;

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

public void Impersonate(string domain, string username, string password)
{
    var isLoggedOn = LogonUser(username, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, 0, out safeTokenHandle);
    if (!isLoggedOn)
    {
        var errorCode = Marshal.GetLastWin32Error();
        throw new ApplicationException(string.Format("Could not impersonate the elevated user. The LogonUser method returned error code {0}.", errorCode));
    }
    impersonationContext = WindowsIdentity.Impersonate(this.safeTokenHandle.DangerousGetHandle());
}
Другие вопросы по тегам