Включение / отключение Aero из службы Windows - PullRequest
1 голос
/ 11 ноября 2008

У меня есть код для включения / отключения службы Windows Aero в Vista, и я хотел бы запустить ее в службе 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;
        }
    }

Ответы [ 2 ]

4 голосов
/ 31 июля 2009

У меня был тот же код ошибки при создании WPF FlowDocuments через сервис, работающий под 64-битной Vista. После копания я могу просмотреть этот пост в Microsoft Connect , который указывает, что

"... Проблема вызвана проблемой взаимодействия с DWM ..."

и

"... это исправит падение WPF во всех услуги, включая IIS7 ... "

Вот прямая ссылка на скачивание исправлений; КБ 959209

Это исправило наши проблемы с запуском юнит-тестов через CruiseControl.Net (CCNet) под управлением 64-битной Vista. Тесты, где хорошо, когда не работает через службу.

1 голос
/ 11 ноября 2008

Не знаю наверняка, но, возможно, вам нужно связать процесс службы с текущим рабочим столом, прежде чем он заработает?

Убедитесь, что ваш сервис может взаимодействовать с рабочим столом. Затем используйте SetThreadDesktop () , чтобы установить рабочий стол для служебного потока, передавая дескриптор рабочему столу с именем «По умолчанию».

Я не пробовал и не могу гарантировать, что это сработает. Но это может быть что-то попробовать?

Удачи:)

...