我在表单应用程序中有一个使用 Cassia 库的函数,该函数将所有通过 rdp 登录的用户返回到会话主机以及有关其会话的一些详细信息(然后将其添加到 datagridview)。
只要您在域中,它就可以正常工作。
但是我想在域外运行这个函数。模拟似乎是可行的方法,但我遇到了问题,我要么得到“错误的用户名或密码”(当我 100% 确定它们是正确的),要么得到一个“访问被拒绝”错误从决明子函数。这意味着模拟没有引发错误,但它也没有工作。
我看到一些地方提到必须在您连接的机器上将注册表代码 AllowRemoteRPC 设置为 1,这已经是这种情况了。
代码(主要是从其他地方复制的):
string serverAddr = "server.com";
string userName = "domainUser"
string uPw = "1234"
IntPtr token;
if (!NativeMethods.LogonUser(userName, serverAddr, uPw, NativeMethods.LogonType.NewCredentials, NativeMethods.LogonProvider.WinNT50, out token))
{
throw new Win32Exception();
}
try
{
IntPtr tokenDuplicate;
if (!NativeMethods.DuplicateToken(token, NativeMethods.SecurityImpersonationLevel.Impersonation, out tokenDuplicate))
{
throw new Win32Exception();
}
try
{
using (WindowsImpersonationContext impersonationContext = new WindowsIdentity(tokenDuplicate).Impersonate())
{
#Do stuff here querying the terminal servers
ITerminalServicesManager manager = new TerminalServicesManager();
IList<ITerminalServer> svs = manager.GetServers("DOMAIN");
int rowCnt = 0;
foreach (ITerminalServer server in svs)
{
server.Open();
string svr = default(string);
string cName = default(string);
string state = default(string);
string uName = default(string);
foreach (ITerminalServicesSession session in server.GetSessions())
{
NTAccount account = session.UserAccount;
uName = session.UserName;
svr = session.Server.ServerName;
cName = session.ClientName;
state = session.ConnectionState.ToString();
if (account != null)
{
userGrid1.Rows.Add();
userGrid1.Rows[rowCnt].Cells[0].Value = uName;
userGrid1.Rows[rowCnt].Cells[1].Value = svr;
userGrid1.Rows[rowCnt].Cells[2].Value = cName;
userGrid1.Rows[rowCnt].Cells[3].Value = state;
rowCnt++;
}
}
}
impersonationContext.Undo();
}
}
finally
{
if (tokenDuplicate != IntPtr.Zero)
{
NativeMethods.CloseHandle(tokenDuplicate);
}
}
}
finally
{
if (token != IntPtr.Zero)
{
NativeMethods.CloseHandle(token);
}
}
}
#the above is all inside a function, NativeMethods class copied below for clarity;
internal static class NativeMethods
{
internal enum LogonType : int
{
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
Unlock = 7,
NetworkCleartext = 8,
NewCredentials = 9
}
internal enum LogonProvider : int
{
Default = 0,
WinNT35 = 1,
WinNT40 = 2,
WinNT50 = 3
}
internal enum SecurityImpersonationLevel : int
{
Anonymous = 0,
Identification = 1,
Impersonation = 2,
Delegation = 3
}
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool LogonUser(
string userName,
string domain,
string password,
LogonType logonType,
LogonProvider logonProvider,
out IntPtr token);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DuplicateToken(
IntPtr existingTokenHandle,
SecurityImpersonationLevel securityImpersonationLevel,
out IntPtr duplicateTokenHandle);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseHandle(IntPtr handle);
}
模拟对我来说很新,所以我可能有一个基本的误解,或者它只是一个语法问题。我不知道。任何帮助,将不胜感激