Я пытаюсь подключиться к компьютеру удаленно, чтобы локально локально копировать локальный каталог. Я пытаюсь использовать вызов функции 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 завершился неудачно ....
У меня такое чувство, что вызывает у меня проблемы. Как мне обойти это?
Существует не изъян виден, код работает отлично. Конечно, вы никогда не используете совершенно неправильное объявление для GetLastError(), оно возвращает * int *. –
если я изменю LogonUser, чтобы вернуть int вместо bool, он все равно возвращает 0 (false) – xtreampb
также ссылка userHandle 0, которая не будет работать при попытке создать WindowsIdentity – xtreampb