【问题标题】:"Win32Exception: The operation completed successfully" after WTSQueryUserToken on 32bit Windows (64bit works)在 32 位 Windows 上 WTSQueryUserToken 后出现“Win32Exception:操作成功完成”(64 位工作)
【发布时间】:2012-07-05 18:54:36
【问题描述】:

我正在用 C# 开发一个小型 Windows 服务,它需要在某些时候与 Win32 API 进行互操作。我收到以下对我没有意义的异常:

System.ComponentModel.Win32Exception: The operation completed successfully

就在这个 C# sn-p 的最后一行之后:

var sessionId = Kernel32.WTSGetActiveConsoleSessionId();
var userTokenPtr = new IntPtr();
if (!WtsApi32.WTSQueryUserToken(sessionId, out userTokenPtr))
{
    throw new Win32Exception(Marshal.GetLastWin32Error());
}

这就是我在WtsApi32 中声明WTSQueryUserToken 的方式:

[DllImport("Wtsapi32.dll", EntryPoint="WTSQueryUserToken")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WTSQueryUserToken
(
    [In, MarshalAs(UnmanagedType.U8)] ulong sessionId, 
    [Out] out IntPtr phToken
);

一些事实:

  • 这在 64 位 Win7 上完美运行,但在 32 位 Win7 上失败
  • 执行此操作时无法到达 10,000 handle limit,这是一个非常小的 Windows 服务中的第一个 Win32 调用。
  • 我认为可能存在一些潜在的 Win32 错误,但一些错误用 0 覆盖了错误代码,因此给了我“成功”错误消息,但我不知道如何确认甚至诊断。
  • 当我捕获异常时,sessionId 为 1,userTokenPtr 为 0。但是,GetLastError 返回 0,所以我不知道发生了什么。
  • 我发现的几乎所有关于这个问题的答案都与improper disposal of user controls 有关。由于这是一项 Windows 服务,情况并非如此

我猜我的 WTSQueryUserToken 声明一定有问题,因为它只在 32 位 Windows 上失败,这让我认为这是一个编组问题。但是,我仍然看不到它可能是什么。

【问题讨论】:

  • 据我所知,boolBOOL 不同。我认为它们的大小不同。你确定 C# 的原型在这方面是正确的吗?
  • 它适用于 x64,这就是我目前所拥有的全部确定性。 :) 或者也许这不是 x64/x86 的区别,而是其他破坏它的东西。我现在正在调查。

标签: c# .net winapi interop win32exception


【解决方案1】:

我们将您的 sessionId 参数定义为 c# ulong - 一个无符号 64 位整数,而实际函数导出需要一个 Win32 ulong - 一个无符号 32 位整数。

c# ulong data type

Win32 data types

【讨论】:

  • 成功了,非常感谢!实际上我已经想到了这一点并尝试UnmanagedType.U4 来修复它,但似乎将ulong 更改为UInt32 就可以了。该行现在显示为:[In, MarshalAs(UnmanagedType.U4)] UInt32 sessionId
  • 64 位与 32 位有时会很棘手。很高兴这次修复如此简单。
猜你喜欢
  • 2012-01-17
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 2015-02-16
  • 2012-04-17
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
相关资源
最近更新 更多