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