среда, 31 октября 2012 г.

C# - Запуск кода с правами администратора

Если еще нужен ответ на вопрос, то вот: попробуйте использовать функцию WindowsIdentity и WindowsImpersonationContext.

примерчик, взятый из MSDN и немного переделанный:

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.Windows.Forms;

[assembly: SecurityPermissionAttribute(SecurityAction.Request­Minimum, UnmanagedCode = true)]
[assembly: PermissionSetAttribute(SecurityAction.RequestMinim­um, Name = "FullTrust")]
public class ImpersonationDemo
{
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    [DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource,
        int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* Arguments);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
        int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

   

 // тестовое использование
        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public static void Main(string[] args)
    {
        IntPtr tokenHandle = new IntPtr(0);
        IntPtr dupeTokenHandle = new IntPtr(0);
        try
        {
            string userName, domainName;
            // получаем пользовательский токен для определения пользователя, домена, и пароля используется небезопасный LogonUser метод
            //Имя локальной машины может быть использовано для доменного имени, чтобы играть роль пользователя этой машины
            Console.Write("Имя домена, на которое регистрироваться: ");
            domainName = Console.ReadLine();

            Console.Write("Имя пользователя, учетной записью которого воспользоваться: ");
            userName = Console.ReadLine();

            Console.Write("Пароль: ");
            const int LOGON32_PROVIDER_DEFAULT = 0;

            //этот параметр вызывает LogonUser, чтобы создать первичный токен
            const int LOGON32_LOGON_INTERACTIVE = 2;
            tokenHandle = IntPtr.Zero;

            //Вызов LogonUser, чтобы получить дескриптор для доступа            
            bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                ref tokenHandle);

            Console.WriteLine("LogonUser вызван.");

            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : {0}", ret);
                throw new System.ComponentModel.Win32Exception(ret);
            }

            Console.WriteLine("LogonUser Успешно? " + (returnValue ? "Yes" : "No"));
            Console.WriteLine("Значение токена: " + tokenHandle);

            // проверить идентификацию            
            Console.WriteLine("Пользователь до подмены учетной записи: " + WindowsIdentity.GetCurrent().Name);

            // Используемый дескриптор токена возвратить LogonUser-у.
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);
            WindowsImpersonationContext impersonatedUser = newId.Impersonate();

            // текущий пользователь
            Console.WriteLine("После подмены учетной записи: " + WindowsIdentity.GetCurrent().Name);

            
            // выйти из-под учетной записи
           impersonatedUser.Undo();

            // текущий пользователь
            Console.WriteLine("После отмены подмены учетной записи: " + WindowsIdentity.GetCurrent().Name);

            // освобождаем токены
            if (tokenHandle != IntPtr.Zero)
            CloseHandle(tokenHandle);
            Console.ReadLine();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Произошла ошибка: " + ex.Message);            
            Console.ReadLine();
        }        
    }
}


Можно ввести учетную запись администратор и спокойно работать с его правами. Надеюсь, это поможет!

Комментариев нет:

Отправить комментарий