当我的程序在运行时,我需要阻止Windows进入睡眠状态。
我不仅想要防止睡眠计时器,我还希望在按下睡眠按钮或以任何其他方式主动让计算机进入睡眠状态时取消睡眠事件。因此,SetThreadExecutionState是不够的。
或者...我实际上不需要完全阻止睡眠,只需要延迟5-10秒以允许我的程序完成任务。
(我知道这是不好的程序行为,但这只是用于个人使用。)
在考虑了vim的答案之后
"使用PowerCreateRequest、PowerSetRequest和PowerClearRequest函数是首选方法。"
通过链接到msdn上的AvailabilityRequests.docx,这个文件太过详细(需要阅读太多),我在网上搜索了一个基于PowerCreateRequest的具体的c#示例,并发现了http://go4answers.webhost4life.com/Example/problem-monitor-wakeup-service-windows7-12092.aspx [编辑2016 - 不再可用]
我将其复制并调整以满足我的需求(从msdn复制的CloseHandle的PInvoke):
using System.Runtime.InteropServices;
#region prevent screensaver, display dimming and automatically sleeping
POWER_REQUEST_CONTEXT _PowerRequestContext;
IntPtr _PowerRequest; //HANDLE
// Availability Request Functions
[DllImport("kernel32.dll")]
static extern IntPtr PowerCreateRequest(ref POWER_REQUEST_CONTEXT Context);
[DllImport("kernel32.dll")]
static extern bool PowerSetRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);
[DllImport("kernel32.dll")]
static extern bool PowerClearRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
internal static extern int CloseHandle(IntPtr hObject);
// Availablity Request Enumerations and Constants
enum PowerRequestType
{
PowerRequestDisplayRequired = 0,
PowerRequestSystemRequired,
PowerRequestAwayModeRequired,
PowerRequestMaximum
}
const int POWER_REQUEST_CONTEXT_VERSION = 0;
const int POWER_REQUEST_CONTEXT_SIMPLE_STRING = 0x1;
const int POWER_REQUEST_CONTEXT_DETAILED_STRING = 0x2;
// Availablity Request Structures
// Note: Windows defines the POWER_REQUEST_CONTEXT structure with an
// internal union of SimpleReasonString and Detailed information.
// To avoid runtime interop issues, this version of
// POWER_REQUEST_CONTEXT only supports SimpleReasonString.
// To use the detailed information,
// define the PowerCreateRequest function with the first
// parameter of type POWER_REQUEST_CONTEXT_DETAILED.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct POWER_REQUEST_CONTEXT
{
public UInt32 Version;
public UInt32 Flags;
[MarshalAs(UnmanagedType.LPWStr)]
public string
SimpleReasonString;
}
[StructLayout(LayoutKind.Sequential)]
public struct PowerRequestContextDetailedInformation
{
public IntPtr LocalizedReasonModule;
public UInt32 LocalizedReasonId;
public UInt32 ReasonStringCount;
[MarshalAs(UnmanagedType.LPWStr)]
public string[] ReasonStrings;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct POWER_REQUEST_CONTEXT_DETAILED
{
public UInt32 Version;
public UInt32 Flags;
public PowerRequestContextDetailedInformation DetailedInformation;
}
#endregion
/// <summary>
/// Prevent screensaver, display dimming and power saving. This function wraps PInvokes on Win32 API.
/// </summary>
/// <param name="enableConstantDisplayAndPower">True to get a constant display and power - False to clear the settings</param>
private void EnableConstantDisplayAndPower(bool enableConstantDisplayAndPower)
{
if (enableConstantDisplayAndPower)
{
// Set up the diagnostic string
_PowerRequestContext.Version = POWER_REQUEST_CONTEXT_VERSION;
_PowerRequestContext.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
_PowerRequestContext.SimpleReasonString = "Continuous measurement"; // your reason for changing the power settings;
// Create the request, get a handle
_PowerRequest = PowerCreateRequest(ref _PowerRequestContext);
// Set the request
PowerSetRequest(_PowerRequest, PowerRequestType.PowerRequestSystemRequired);
PowerSetRequest(_PowerRequest, PowerRequestType.PowerRequestDisplayRequired);
}
else
{
// Clear the request
PowerClearRequest(_PowerRequest, PowerRequestType.PowerRequestSystemRequired);
PowerClearRequest(_PowerRequest, PowerRequestType.PowerRequestDisplayRequired);
CloseHandle(_PowerRequest);
}
}
我曾经遇到过一个通过 USB 连接的硬件设备的问题。XP/Vista 会在中途进入睡眠/休眠状态...你可能会说,它恢复后可以继续工作。但是如果硬件仍然连接着呢?!
用户有随时拔掉电缆的习惯。
你需要处理 XP 和 Vista。
在 XP 下,捕获 WM_POWERBROADCAST 并查找 PBT_APMQUERYSUSPEND wparam。
// See if bit 1 is set, this means that you can send a deny while we are busy
if (message.LParam & 0x1)
{
// send the deny message
return BROADCAST_QUERY_DENY;
} // if
else
{
return TRUE;
} // else
在Vista下使用SetThreadExecutionState,像这样
// try this for vista, it will fail on XP
if (SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED) == NULL)
{
// try XP variant as well just to make sure
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
} // if
当你的应用程序完成后,将其设置回正常状态。
// set state back to normal
SetThreadExecutionState(ES_CONTINUOUS);
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
这个函数在WinXP上能用吗? - Noitidart使用 PowerCreateRequest、PowerSetRequest 和 PowerClearRequest 函数是首选方法。详细信息和示例代码(C/C#)在http://msdn.microsoft.com/en-us/library/windows/hardware/gg463205.aspx中。
设置wsc = CreateObject("WScript.Shell")
做 WScript.Sleep (60*1000) wsc.SendKeys ("{SCROLLLOCK 2}") 循环
-将上述代码放入记事本并将文件保存为.vbs,然后双击该文件即可。
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
完成应用程序后,请确保清除所有其他标志。
SetThreadExecutionState(ES_CONTINUOUS);
SetThreadExecutionState
)的尝试,如vim建议的。using Vanara.PInvoke;
using static Vanara.PInvoke.Kernel32;
// create request object
using var request = PowerCreateRequest(new REASON_CONTEXT("App FOO is working"));
if (request.IsInvalid)
{
throw new InvalidOperationException(
$"Could not create power availability request: {Win32Error.GetLastError()}");
}
// send request
if (!PowerSetRequest(request, POWER_REQUEST_TYPE.PowerRequestSystemRequired))
{
throw new InvalidOperationException(
$"Could not send power availability request: {Win32Error.GetLastError()}");
}
// do stuff that required the machine to be up
Console.WriteLine("Doing stuff...");
await Task.Delay(5000);
// clear request
if (!PowerClearRequest(request, POWER_REQUEST_TYPE.PowerRequestSystemRequired))
{
Console.WriteLine(
"WARNING: Could not clear power availability request: {0}",
Win32Error.GetLastError());
}
您可以通过在管理员终端中输入powercfg /requests
来查看您的请求执行情况。