监测远程登录(会话)的问题(WTSEnumerateSessions()) 请教高手

zhangning111 2009-03-11 11:21:48
我想用WTSEnumerateSessions()函数枚举会话,就如同net session命令和[共享文件夹-会话]功能一样。但是只能枚举出一个本机的,不能枚举出其它远程用户的,这是为什么呢?

我是vs2008 c# winxp环境。

附程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

//using System.Management;
using System.Runtime;
using System.Runtime.InteropServices;

namespace AutoLogOffSession
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
TSControl.WTS_SESSION_INFO[] pSessionInfo = TSControl.SessionEnumeration();

for (int i = 0; i < pSessionInfo.Length; i++)
{
//if (pSessionInfo[i].SessionID != 0)
{
try
{
int count = 0;
IntPtr buffer = IntPtr.Zero;
StringBuilder sb = new StringBuilder();
bool bsuccess = TSControl.WTSQuerySessionInformation(IntPtr.Zero, pSessionInfo[i].SessionID, TSControl.WTSInfoClass.WTSUserName, out sb, out count);
if (bsuccess)
{
MessageBox.Show(sb.ToString());
}
bsuccess = TSControl.WTSQuerySessionInformation(IntPtr.Zero, pSessionInfo[i].SessionID, TSControl.WTSInfoClass.WTSConnectState, out sb, out count);
if (bsuccess)
{
MessageBox.Show(sb.ToString());
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
}
public class TSControl
{
[DllImport("wtsapi32", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool WTSEnumerateSessions(int hServer, int Reserved, int Version, ref long ppSessionInfo, ref int pCount);

[DllImport("wtsapi32.dll")]
public static extern void WTSFreeMemory(System.IntPtr pMemory);

[DllImport("wtsapi32.dll")]
public static extern bool WTSLogoffSession(int hServer, long SessionId, bool bWait);
[DllImport("Wtsapi32.dll")]
public static extern bool WTSQuerySessionInformation(
System.IntPtr hServer, int sessionId, WTSInfoClass wtsInfoClass, out StringBuilder ppBuffer, out int pBytesReturned);

public enum WTSInfoClass
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType
}

public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit,
}

public struct WTS_SESSION_INFO
{
public int SessionID;
[MarshalAs(UnmanagedType.LPTStr)]
public string pWinStationName;
public WTS_CONNECTSTATE_CLASS state;
}

public static WTS_SESSION_INFO[] SessionEnumeration()
{
//Set handle of terminal server as the current terminal server
int hServer = 0;
bool RetVal;
long lpBuffer = 0;
int Count = 0;
long p;
WTS_SESSION_INFO Session_Info = new WTS_SESSION_INFO();
WTS_SESSION_INFO[] arrSessionInfo;
RetVal = WTSEnumerateSessions(hServer, 0, 1, ref lpBuffer, ref Count);
arrSessionInfo = new WTS_SESSION_INFO[0];
if (RetVal)
{
arrSessionInfo = new WTS_SESSION_INFO[Count];
int i;
p = lpBuffer;
for (i = 0; i < Count; i++)
{
arrSessionInfo[i] = (WTS_SESSION_INFO)Marshal.PtrToStructure(new IntPtr(p), Session_Info.GetType());
p += Marshal.SizeOf(Session_Info.GetType());
}
WTSFreeMemory(new IntPtr(lpBuffer));
}
else
{
//Insert Error Reaction Here
}
return arrSessionInfo;
}
}
}
...全文
870 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
chmdcr 2009-06-03
  • 打赏
  • 举报
回复
我用WTSEnumerateSessions取的 也是在xp sp2下可以 在sp3 下和 visita下 就不行 天啊
zhangning111 2009-03-12
  • 打赏
  • 举报
回复
俺对gomoku的敬仰之情如滔滔江水连绵不决,如长江入海一发不可收拾

为什么net session命令用zhz 而netsessiondel函数用zhaowei呢,UncClientName 参数是对应的什么呢

还有 netsessiondel执行一次不一定成功,貌似要多执行几次
gomoku 2009-03-12
  • 打赏
  • 举报
回复
第三个参数,如果设置,应指向用户名(ZHAOWEI)。
zhangning111 2009-03-12
  • 打赏
  • 举报
回复
net session zhz /d 是怎么实现的
zhangning111 2009-03-12
  • 打赏
  • 举报
回复
我现在用net session查询如下

计算机 用户名 客户类型 打开空闲时间
----------------------------------------------------------------------------
\\ZHZ ZHAOWEI Windows 2002 Serv 0 00:14:29

现在我用NetSessionDel函数关闭会话,前两个参数为null,第三个参数为指向“zhz”的指针,这样用有什么问题呢?
请高人指点迷津。

附netsessiondel函数文档:
NET_API_STATUS NetSessionDel(
__in LPWSTR servername,
__in LPWSTR UncClientName,
__in LPWSTR username
);
Parameters
servername [in]
Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is NULL, the local computer is used.

UncClientName [in]
Pointer to a string that specifies the computer name of the client to disconnect. If the UncClientName parameter is NULL, then all the sessions of the user identified by the username parameter will be deleted on the server specified by the servername parameter. For more information, see NetSessionEnum.

username [in]
Pointer to a string that specifies the name of the user whose session is to be terminated. If this parameter is NULL, all users' sessions from the client specified by the UncClientName parameter are to be terminated.

Return Value
If the function succeeds, the return value is NERR_Success.


gomoku 2009-03-12
  • 打赏
  • 举报
回复
2312是NERR_ClientNameNotFound(NERR_BASE+212,NERR_BASE=2100)。
建议先用C++试验,然后再移植到C#。
zhangning111 2009-03-12
  • 打赏
  • 举报
回复
感谢gomoku大虾:

俺用c# 运行了netsessionenum也得到了结果(类型SESSION_INFO_10)
现在俺想用netsessiondel关闭会话,结果失败了,当参数全为null时,返回错误87-参数错误,
前连个参数为null最后一个为用户名时,返回错误2312(0x908),msdn里没这个错误码
望大虾指点
zhangning111 2009-03-12
  • 打赏
  • 举报
回复
太不幸了,netsessiondel在xp下好的,在vista下失效了
zhangning111 2009-03-12
  • 打赏
  • 举报
回复
大虾咋还不来呢
mjjzg 2009-03-11
  • 打赏
  • 举报
回复
路过,UP
gomoku 2009-03-11
  • 打赏
  • 举报
回复
建议先检查一下WTSEnumerateSessions中的会话和net session中的会话是否同一个概念。

WTSEnumerateSessions中的会话是Terminal Service的概念。
比如第一个用户一般在Console会话,而随后快速切换用户将增加另一个会话。
gomoku 2009-03-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zhangning111 的回复:]
首先感谢LS:
俺刚在msdn发现NetSessionEnum() 这个函数就看到了楼上的回复

现在俺正想办法让msdn例子运行起来,就是老报错Error 2 error LNK2019: unresolved external symbol _NetSessionEnum@36 referenced in function _wmain netsessionenum.obj netsessionenum

[/Quote]

要链接到Netapi32.lib,可以在工程设置中做,或加这一行:

#include <lm.h>
#pragma comment(lib, "Netapi32.lib") //<----
callmesai 2009-03-11
  • 打赏
  • 举报
回复
mark~
zhangning111 2009-03-11
  • 打赏
  • 举报
回复
自己顶顶
zhangning111 2009-03-11
  • 打赏
  • 举报
回复
首先感谢LS:
俺刚在msdn发现NetSessionEnum() 这个函数就看到了楼上的回复

现在俺正想办法让msdn例子运行起来,就是老报错Error 2 error LNK2019: unresolved external symbol _NetSessionEnum@36 referenced in function _wmain netsessionenum.obj netsessionenum


#ifndef UNICODE
#define UNICODE
#endif

#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <lm.h>

int wmain(int argc, wchar_t *argv[])
{
LPSESSION_INFO_10 pBuf = NULL;
LPSESSION_INFO_10 pTmpBuf;
DWORD dwLevel = 10;
DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
DWORD dwEntriesRead = 0;
DWORD dwTotalEntries = 0;
DWORD dwResumeHandle = 0;
DWORD i;
DWORD dwTotalCount = 0;
LPTSTR pszServerName = NULL;
LPTSTR pszClientName = NULL;
LPTSTR pszUserName = NULL;
NET_API_STATUS nStatus;
//
// Check command line arguments.
//
if (argc > 4)
{
wprintf(L"Usage: %s [\\\\ServerName] [\\\\ClientName] [UserName]\n", argv[0]);
exit(1);
}

if (argc >= 2)
pszServerName = argv[1];

if (argc >= 3)
pszClientName = argv[2];

if (argc == 4)
pszUserName = argv[3];
//
// Call the NetSessionEnum function, specifying level 10.
//
do // begin do
{
nStatus = NetSessionEnum(pszServerName,
pszClientName,
pszUserName,
dwLevel,
(LPBYTE*)&pBuf,
dwPrefMaxLen,
&dwEntriesRead,
&dwTotalEntries,
&dwResumeHandle);
//
// If the call succeeds,
//
if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA))
{
if ((pTmpBuf = pBuf) != NULL)
{
//
// Loop through the entries.
//
for (i = 0; (i < dwEntriesRead); i++)
{
assert(pTmpBuf != NULL);

if (pTmpBuf == NULL)
{
fprintf(stderr, "An access violation has occurred\n");
break;
}
//
// Print the retrieved data.
//
wprintf(L"\n\tClient: %s\n", pTmpBuf->sesi10_cname);
wprintf(L"\tUser: %s\n", pTmpBuf->sesi10_username);
printf("\tActive: %d\n", pTmpBuf->sesi10_time);
printf("\tIdle: %d\n", pTmpBuf->sesi10_idle_time);

pTmpBuf++;
dwTotalCount++;
}
}
}
//
// Otherwise, indicate a system error.
//
else
fprintf(stderr, "A system error has occurred: %d\n", nStatus);
//
// Free the allocated memory.
//
if (pBuf != NULL)
{
NetApiBufferFree(pBuf);
pBuf = NULL;
}
}
//
// Continue to call NetSessionEnum while
// there are more entries.
//
while (nStatus == ERROR_MORE_DATA); // end do

// Check again for an allocated buffer.
//
if (pBuf != NULL)
NetApiBufferFree(pBuf);
//
// Print the final count of sessions enumerated.
//
fprintf(stderr, "\nTotal of %d entries enumerated\n", dwTotalCount);

return 0;
}
oyljerry 2009-03-11
  • 打赏
  • 举报
回复
NetSessionEnum()

http://www.lis123.com/Article/Dev/Programme/Delphi/20071204_5802.html
zhangning111 2009-03-11
  • 打赏
  • 举报
回复
额,检查什么啊
wonder888888 2009-03-11
  • 打赏
  • 举报
回复
检查一下
zhangning111 2009-03-11
  • 打赏
  • 举报
回复
to:gomoku

俺就是想做个类似 [我的电脑(右键)-管理-共享文件夹-会话]中的会话这样的软件,显示都那些计算机在访问我,不知道用什么api比较好,请高手指点。

110,565

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧