1

ある時点でWin32APIと相互運用する必要がある小さなWindowsサービスをC#で開発しています。次の例外が発生しますが、これは私には意味がありません。

System.ComponentModel.Win32Exception: The operation completed successfully

このC#スニペットの最後の行の直後:

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

これが私が宣言WTSQueryUserTokenしている方法ですWtsApi32

[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ハンドル制限に達する方法はありません。これは、非常に小さなWindowsサービスでの最初のWin32呼び出しです。
  • 根本的なWin32エラーがあるかもしれないと思いますが、いくつかのバグがエラーコードを0で上書きし、「成功」エラーメッセージを表示しますが、これを確認または診断する方法がわかりません。
  • 例外をキャッチすると、sessionIdは1、userTokenPtrは0です。ただし、GetLastErrorは0を返すため、何が起こったのかわかりません。
  • この問題に対して私が見つけたほとんどすべての答えは、ユーザーコントロールの不適切な廃棄に関係していました。これはWindowsサービスであるため、そうではありません

WTSQueryUserToken宣言は32ビットWindowsでしか失敗しないため、何か問題があるに違いないと思います。これは、マーシャリングの問題だと思います。しかし、それが何であるかはまだわかりません。

4

1 に答える 1

4

sessionIdパラメーターはac#ulong(符号なし64ビット整数)として定義されていますが、実際の関数エクスポートでは、Win32 ulong(符号なし32ビット整数)が必要です。

c#ulongデータ型

Win32データ型

于 2012-07-05T19:04:59.173 に答える