1

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;
        }
    }
4

2 に答える 2

4

64ビットVistaで実行されているサービスを介してWPFFlowDocumentsを作成したときに、同じエラーコードが発生しました。掘り下げた後、MicrosoftConnectに関するこの投稿に出くわすことができます。

「...この問題は、DWMとの相互運用の問題が原因で発生します...」

「...IIS7を含むすべてのサービスでのWPFクラッシュが修正されます...」

ホットフィックスのダウンロードへの直接リンクは次のとおりです。KB 959209

これにより、64ビットVistaを実行しているCruiseControl.Net(CCNet)を介して単体テストを実行する際の問題が修正されました。サービスを実行していないときに問題がない場合のテスト。

于 2009-07-31T07:33:58.257 に答える
1

確かなことはわかりませんが、サービスのプロセスを現在のデスクトップに関連付ける必要があるかもしれません。

サービスがデスクトップと対話できることを確認してください。次に、SetThreadDesktop()を使用して、「デフォルト」と呼ばれるデスクトップへのハンドルを渡すサービス スレッドのデスクトップを設定します。

私はそれを試していないので、うまくいくとは保証できません。しかし、それは試してみるものかもしれませんか?

幸運を :)

于 2008-11-11T10:13:39.267 に答える