微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尝试枚举终端服务器会话会产生AccessViolationException.NET和本机DLL

如何解决尝试枚举终端服务器会话会产生AccessViolationException.NET和本机DLL

我正在尝试使用WtsEnumerateSessionsExA中定义的功能WtsApi32.dll枚举C#中的所有远程桌面会话。

函数将其指针作为参数传递的WTS_SESSION_INFO_1A结构数组写入。您可以在此处找到文档:

我已经在C#中实现了WTS_SESSION_INFO_1A结构和WTS_CONNECT_STATE_CLASS,如下所示:

struct WtsSessionInfoClass
{
    uint ExecEnvId;
    WtsConnectStateClass state;
    uint sessionId;
    string pSessionName;
    string pHostName;
    string pUserName;
    string pDomainName;
    string pFarmName;
}
enum WtsConnectStateClass
{
    WTSActive,WTSConnected,WTSConnectQuery,WTSShadow,WTSdisconnected,WTSIdle,WTSListen,WTSReset,WTSDown,WTSInit
}

我已经在名为Native32的类中导入了所需的功能

[DllImport("WtsApi32.dll")]
internal static extern IntPtr WTSOpenServerEx(string name);

[DllImport("WtsApi32.dll")]
internal static extern bool WTSEnumerateSessionsExA(
    IntPtr hServer,UIntPtr pLevel,uint Filter,out WtsSessionInfoClass[] ppSessionInfo,UIntPtr pCount
);

最后,我的实现如下:

UIntPtr len = new UIntPtr();
WtsSessionInfoClass[] sessions;
IntPtr handle = Native32.WTSOpenServerEx("MyMachineName"); // This function gets the server handle and works fine
Native32.WTSEnumerateSessionsExA(handle,new UIntPtr(1),out sessions,len); // This function will produce AccessViolationException
...

执行代码时,由于Native32.WTSEnumerateSessionsExA,对AccessViolationException调用失败。

在这里做错了什么?任何帮助表示赞赏。

解决方法

我最好的猜测是您没有正确地传递第二个参数pLevel。您正试图传递一个指向值为1的DWORD的指针,但实际上传递的是地址1。相反,声明一个初始化为1的局部变量,然后传递该地址。

更多详细信息:

您链接的WTSEnumerateSessionsExA的文档页面上说:

pLevel

此参数保留。始终将此参数设置为一个。在输出时, WTSEnumerateSessionsEx 不会更改此参数的值。

这里的措辞不是最好的,但是我的解释是您需要传递pLevel的有效指针,并且该指针需要指向值为1的正确对齐的DWORD。

对我来说,另一种读法是您需要传递文字存储地址1作为pLevel的指针。我本能地觉得这很荒谬。

但是,您的代码:

Native32.WTSEnumerateSessionsExA(
  handle,new UIntPtr(1),out sessions,len);

传入new UIntPtr(1)的{​​{1}}。根据我对UIntPtr doc pages的阅读,该表达式将创建一个指针,其字面值为1,即地址1。

如果您调试了WTSEnumerateSessionsEx实现的汇编代码,我的猜测是您会看到它尝试取消对pLevel的引用,然后崩溃,并在尝试从地址加载DWORD时遇到访问冲突1。

要解决此问题,您可以声明一个包含值1的pLevel变量,并将地址传递给该变量:

uint

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。