2015-04-09 3 views
0

Я пытаюсь подключиться к компьютеру удаленно, чтобы локально локально копировать локальный каталог. Я пытаюсь использовать вызов функции LogonUser, найденный в DLL advapi32. Когда я вызываю функцию, она возвращает 0 (false), но когда я вызываю Marshal.GetLastWin32Error(), которая также возвращает 0, что указывает на отсутствие ошибки. Имя пользователя и пароль, которые я пытаюсь использовать, я знаю, потому что я использую его для входа на компьютер. Я использовал как доменные, так и локальные учетные записи, и оба возвращают одинаковый результат. Ниже приведена моя попытка входа на компьютер.LogonUser возвращает 0 и GetLastError также возвращает 0

[DllImport("advapi32.DLL", SetLastError = true)] 
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLongonType, int dwLogonProvider, ref IntPtr phToken); 

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

[DllImport("kernel32.DLL", CharSet = CharSet.Auto)] 
public static extern string GetLastError(); 

private static void CopyDirectory(string computerName, string localPath, string remotePath) 
{ 
    WindowsImpersonationContext impersonationContext = null; 
    IntPtr userHandle = IntPtr.Zero; 
    string username = @"testing"; 
    string password = @"testing"; 

    string fullRemotePath = string.Format("{0}\\{1}", computerName, remotePath); 

    try 
    { 

     bool Logon = LogonUser(username, computerName, password, 2, 0, ref userHandle); 
     if (!Logon) 
     { 
      Console.WriteLine("Error Logging in"); 
      int errorCode = Marshal.GetLastWin32Error(); 
      Console.WriteLine(string.Format("Error Code: {0}", errorCode)); 
      Console.WriteLine(new Win32Exception(errorCode).Message); 
     } 

     else 
     { 
      WindowsIdentity user = new WindowsIdentity(userHandle); 
      impersonationContext = user.Impersonate(); 

      System.IO.File.Copy(localPath, fullRemotePath, true); 
     } 

    } 

    catch (Exception ex) 
    { 
     int errorCode = Marshal.GetLastWin32Error(); 
     Console.WriteLine(string.Format("Error Code: {0}", errorCode)); 
     Console.WriteLine(ex.Message); 
    } 

    finally 
    { 
     if(impersonationContext != null) 
      impersonationContext.Undo(); 

     if(userHandle != IntPtr.Zero) 
      CloseHandle(userHandle); 

    } 
} 

Не могли бы вы помочь мне найти мой недостаток?

EDIT: я нашел следующий комментарий here

Даже если API поддерживает SetLastError/GetLastError, значение, возвращаемое GetLastError имеет смысл только в случае, если API просто называется на самом деле не удается. Как указывается этот отказ, зависит от API. За исключением нескольких сочетаний API/ситуаций Braindead, таких как Impersonate * с новым SeImpersonatePrivilege: API может вернуть код успеха, даже если он не работает из-за отсутствия привилегий, оставив вам только идентификационный токен. Затем вам нужно позвонить GetLastError(), чтобы узнать, почему номинально успешный вызов API завершился неудачно ....

У меня такое чувство, что вызывает у меня проблемы. Как мне обойти это?

+0

Существует не изъян виден, код работает отлично. Конечно, вы никогда не используете совершенно неправильное объявление для GetLastError(), оно возвращает * int *. –

+0

если я изменю LogonUser, чтобы вернуть int вместо bool, он все равно возвращает 0 (false) – xtreampb

+0

также ссылка userHandle 0, которая не будет работать при попытке создать WindowsIdentity – xtreampb

ответ

0

Так что я был над анализом своей проблемы и решения. По-видимому, мне может не понадобиться использовать UserLogon, так как This answer работает в моей тестовой среде. Посмотрим, работает ли это, когда я его использую.

Edit: Результаты Это все работало для меня просто было создать пользователя на моем сервере с теми же учетными данными (имя пользователя/пароль) и могли увидеть другие компьютеры на рабочей группе

Смежные вопросы