2008-11-11 136 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”的桌面的句柄的桌面。

我还没有尝试过,我不能保证它能正常工作。但它可能是一些尝试?

祝你好运:)