2012-07-05 59 views
1

我正在開發一個C#中的小型Windows服務,需要在某個時間點與Win32 API互操作。我得到以下異常這沒有任何意義對我說:32位Windows(64位作品)上的WTSQueryUserToken後的「Win32Exception:操作成功完成」

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()); 
} 

這裏是我如何在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錯誤,但有些bug用0覆蓋了錯誤代碼,從而給我「成功」的錯誤信息,但我不知道如何確認或甚至診斷此錯誤。
  • 當我發現異常時,sessionId是1,userTokenPtr是0.但是,GetLastError返回0,所以我不知道發生了什麼。
  • 幾乎我發現這個問題的所有答案都與improper disposal of user controls有關。由於這是Windows服務,因此並非

我猜都必須有我的WTSQueryUserToken聲明做錯事,因爲它僅在32位Windows,這使我覺得這是一個編組問題失敗。但是,我仍然看不到它可能是什麼。

+1

'bool'是不一樣的'BOOL'據我所知。我認爲他們的大小不同。你確定C#的原型在這個燈光下是正確的嗎? – 0xC0000022L 2012-07-05 18:57:54

+0

它適用於x64,這是迄今爲止我所有的確定性。 :)或者,它可能不是x64/x86的區別,但是其他的東西正在破壞它。我現在正在研究它。 – 2012-07-05 19:05:16

回答

4

您的sessionId參數定義爲c#ulong - 一個無符號的64位整數,而實際的函數導出期望爲一個Win32 ulong - 一個無符號的32位整數。

c# ulong data type

Win32 data types

+0

它的作品,非常感謝你!其實我已經想到了這一點,並試圖'UnmanagedType.U4'來解決它,但它似乎正在改變'ulong'到'UInt32',這有伎倆。該行現在顯示爲:[[,MarshalAs(UnmanagedType.U4)] UInt32 sessionId'。 – 2012-07-05 19:18:11

+0

64bit vs 32bit有時可能會非常棘手。很高興這次修復非常簡單。 – 2012-07-06 04:29:51

相關問題