В приложении, которое я написал несколько лет назад, я использую функцию SystemParametersInfo с SPI_GETPOWEROFFTIMEOUT, чтобы отключить время ожидания для монитора. В Vista это больше не работает.
Поэтому я решил заставить эту работу работать на Vista, но через несколько часов я чувствую, что не ближе к решению.
Большинство функций, о которых я собираюсь упомянуть, описаны в http://msdn.microsoft.com/en-us/library/aa373163(VS.85).aspx
Насколько я понимаю, я должен:
1. использовать функцию PowerGetActiveScheme, чтобы получить текущую схему
2. использовать PowerEnumerate с GUID_VIDEO_SUBGROUP
3. используйте PowerReadACValue (или значение DC), чтобы получить значение.
Это правильно? Похоже, много работы, чтобы добраться до одной настройки. Если это правильный путь, есть одна вещь, которую я не понимаю. В моей системе PowerEnumerate возвращает 3 ключа. Как узнать, какой из них предназначен для тайм-аута монитора?
Вот мой код. У меня проблемы с PowerReadACValue, возможно, я не определил или не использовал его должным образом.
class Program
{
[DllImport("powrprof.dll")]
static extern UInt32 PowerGetActiveScheme(IntPtr UserRootPowerKey, ref IntPtr ActivePolicyGuid);
[DllImport("powrprof.dll")]
static extern uint PowerEnumerate(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
Guid SubGroupOfPowerSettingGuid,
UInt32 AcessFlags,
UInt32 Index,
ref Guid Buffer,
ref UInt32 BufferSize);
[DllImport("powrprof.dll")]
static extern uint PowerReadACValue(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
IntPtr SubGroupOfPowerSettingGuid,
Guid PowerSettingGuid,
ref IntPtr Type,
ref IntPtr Buffer,
ref UInt32 BufferSize);
static void Main(string[] args)
{
IntPtr activeGuidPtr = IntPtr.Zero;
uint res = PowerGetActiveScheme(IntPtr.Zero, ref activeGuidPtr);
if (res == 0)
{
Guid VideoSettingGuid = new Guid();
UInt32 index = 0;
UInt32 BufferSize = (UInt32)Marshal.SizeOf(typeof(Guid));
while (0 == PowerEnumerate(
IntPtr.Zero, activeGuidPtr, new Guid("7516b95f-f776-4464-8c53-06167f40cc99"), 18, index, ref VideoSettingGuid, ref BufferSize))
{
Console.Write(VideoSettingGuid.ToString() + ": ");
UInt32 size = 1024;
IntPtr temp = Marshal.AllocHGlobal(1024);
IntPtr type = IntPtr.Zero;
PowerReadACValue(IntPtr.Zero, activeGuidPtr, IntPtr.Zero, VideoSettingGuid, ref type, ref temp, ref size);
Console.Write(Marshal.PtrToStringUni(temp));
Marshal.FreeHGlobal(temp);
index++;
}
}
}
}
Я также пытался использовать GetActivePwrScheme, а затем ReadPwrScheme, но, похоже, он тоже не работает. GetActivePwrScheme всегда возвращает 0, даже если я переключаю схемы питания. Я также попытался запустить ReadPwrScheme с инкрементными значениями (1,2,3). Я получил 5 или 6, но он никогда не возвращал правильное число для значения, установленного для тайм-аута монитора на панели управления.
Надеюсь, у меня это совершенно неправильно, и есть гораздо более простой способ сделать это.