我有一些代码可以在 Vista 中启用/禁用 Windows Aero 服务,我想在 Windows 服务中运行它。该代码在独立应用程序中工作,但是当我从服务运行它时,什么也没有发生。不会引发任何错误或异常。
我意识到在服务中运行代码与在应用程序中运行代码的范围不同,但在这种情况下,我将如何从服务中启用/禁用 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;
}
}