我正在尝试远程登录到计算机,以便我可以在本地复制本地目录 . 我正在尝试使用advapi32 DLL中的LogonUser函数调用 . 当我调用该函数时,它返回0(false)但是当我调用Marshal.GetLastWin32Error()时也返回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);
}
}
你能帮助我找到我的缺陷吗?
编辑:我发现了以下评论here
即使API支持SetLastError / GetLastError,GetLastError返回的值仅在您刚调用的API实际失败时才有意义 . 如何指示失败取决于API . 除了一些脑卒中API /情境组合,例如Impersonate *和新的SeImpersonatePrivilege:即使由于缺少权限而失败,API也可以返回成功代码,只留下一个识别令牌 . 然后你必须调用GetLastError()来找出名义上成功的API调用失败的原因....
我有一种感觉,这就是导致我出现问题的原因 . 我该如何解决这个问题?
2 回答
所以我在分析我的问题和解决方案 . 显然我可能不需要使用UserLogon,因为This answer在我的测试环境中工作 . 让我看看我使用它时是否有效 .
编辑:结果这一切对我来说只是必须在我的服务器上创建一个具有相同凭据(用户名/密码)的用户,并可以看到工作组上的其他计算机
我最终通过使用Windows登录凭据解决了这个问题 . 因此,如果“用户名/密码”是您的Windows登录,那么只需在“LogonUser”方法中使用相同的“用户名/密码” . 希望能帮助到你 .