2008-11-11 141 views
1

我有一些代碼來啓用/禁用Vista中的Windows Aero服務,並且我想在Windows服務中運行它。該代碼在獨立應用程序中工作,但是當我從服務運行它時,什麼都不會發生。沒有錯誤或異常被拋出。從Windows服務啓用/禁用Aero

我意識到在服務中運行代碼與在應用程序中運行代碼的範圍不同,但在這種情況下,我將如何從服務啓用/禁用Aero?這甚至有可能嗎?

這裏是我一起工作的代碼:

public static readonly uint DWM_EC_DISABLECOMPOSITION = 0; 
public static readonly uint DWM_EC_ENABLECOMPOSITION = 1; 

[DllImport("dwmapi.dll", EntryPoint="DwmEnableComposition")] 
protected static extern uint Win32DwmEnableComposition(uint uCompositionAction); 

public static bool EnableAero() 
{ 
    Win32DwmEnableComposition(DWM_EC_ENABLECOMPOSITION); 
} 

編輯:

事實證明,該DwmEnableComposition調用返回HRESULT 0x80070018,或ERROR_BAD_LENGTH。看起來像一個奇怪的錯誤,因爲代碼不作爲服務運行時工作。

我也嘗試將整個事情改爲下面的代碼,但得到了相同的結果。它設置窗口站和桌面,並且它看起來是正確的,但調用DwmEnableComposition會導致相同的錯誤。爲了簡潔,我沒有包含PInvoke聲明。

protected override void OnStop() 
    { 
     IntPtr winStation = OpenWindowStation("winsta0", true, 0x10000000 /* GENERIC_ALL */); 
     if (winStation == null || winStation.ToInt32() == 0) 
     { 
      String err = new Win32Exception(Marshal.GetLastWin32Error()).Message; 
     } 

     if (!SetProcessWindowStation(winStation)) 
     { 
      String err = new Win32Exception(Marshal.GetLastWin32Error()).Message; 
     } 

     uint thread = GetCurrentThreadId(); 

     IntPtr hdesk = OpenInputDesktop(0, false, 0x10000000 /* GENERIC_ALL */); 
     if (hdesk == null || hdesk.ToInt32() == 0) 
     { 
      String err = new Win32Exception(Marshal.GetLastWin32Error()).Message; 
     } 

     if (!SetThreadDesktop(hdesk)) 
     { 
      String err = new Win32Exception(Marshal.GetLastWin32Error()).Message; 
     } 

     uint result = Win32DwmEnableComposition(DWM_EC_DISABLECOMPOSITION); 
     if (result != 0) 
     { 
      String err = new Win32Exception(Marshal.GetLastWin32Error()).Message; 
     } 
    } 

回答

4

我有同樣的錯誤代碼,通過服務創造WPF FlowDocuments在64位Vista上運行時。周圍挖後,我可以進行的跨this post on Microsoft Connect,其中指出

「......問題是由一個互操作問題與DWM造成的......」

「...它將修復所有 服務(包括IIS7)中的WPF崩潰...」

這裏是直接li nk到hot-fix下載; KB 959209

這解決了我們通過運行64位Vista的CruiseControl.Net(CCNet)運行單元測試的問題。在沒有通過服務運行的情況下,測試可以罰款。

1

我不知道確定,但也許你需要將你的服務的進程與當前桌面關聯,然後才能工作?

確保您的服務可以與桌面交互。然後使用SetThreadDesktop()來設置服務線程傳遞到名爲「Default」的桌面的句柄的桌面。

我還沒有嘗試過,我不能保證它能正常工作。但它可能是一些嘗試?

祝你好運:)