如何获取线程执行状态?
在 Windows 上,每个线程都有一个执行状态,可以通过调用 SetThreadExecutionState
。例如,如果一个线程调用:
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED)
那么 Windows 将不会关闭显示,直到该线程更改其执行状态或终止。
可以从 C# 访问它:
[DllImport("kernel32.dll", SetLastError = true)] SetThreadExecutionState(...)
但是,虽然 SetThreadExecutionState
设置执行状态,但似乎没有任何等效的 GetThreadExecutionState
API。 kernel32.dll
导出 SetThreadExecutionState
,但不导出 GetThreadExecutionState
。我尝试过:
[DllImport("kernel32.dll", SetLastError = true)] internal static extern uint GetThreadExecutionState();
但我得到一个 System.EntryPointNotFoundException ,说 GetThreadExecutionState
不存在于 kernel32.dll
中。
那么如何在不改变当前线程的情况下找出它的执行状态呢?
On Windows, each thread has an execution state which can be set by calling SetThreadExecutionState
. For example, if a thread calls:
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED)
then Windows will not turn off the display, until that thread changes its execution state, or terminates.
It can be accessed from C#:
[DllImport("kernel32.dll", SetLastError = true)] SetThreadExecutionState(...)
But, while SetThreadExecutionState
sets the execution state, there doesn't appear to be any equivalent GetThreadExecutionState
API. kernel32.dll
exports SetThreadExecutionState
but not GetThreadExecutionState
. I tried:
[DllImport("kernel32.dll", SetLastError = true)] internal static extern uint GetThreadExecutionState();
But I got a System.EntryPointNotFoundException
saying GetThreadExecutionState
does not exist in kernel32.dll
.
How then can I find out the execution state of the current thread without changing it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
SetThreadExecutionState
执行两项不同的操作:它会执行 (1) 当您传入
ES_CONTINUOUS
时;否则就是(2)。因此,如果您不传递
ES_CONTINUOUS
作为输入,它不会更改当前线程的执行标志,只会重置空闲计时器。重置空闲计时器时,
ES_SYSTEM_REQUIRED
告诉它重置系统空闲计时器,ES_DISPLAY_REQUIRED
告诉它重置显示器空闲计时器。如果您未传递ES_SYSTEM_REQUIRED
或ES_DISPLAY_REQUIRED
中的任何一个,则不会重置任何空闲计时器。换句话说,
SetThreadExecutionState(0)
本质上是一个无操作 - 它不会更改线程的执行标志,也不会重置任何空闲计时器。但它确实做了一些有用的事情——它返回线程执行标志的当前值。因此,您要查找的
GetThreadExecutionState
不存在,但您也不需要它,因为SetThreadExecutionState(0)
是等效的。请注意,返回值始终包含
ES_CONTINUOUS
。因此,如果您的线程没有设置任何执行状态标志,则SetThreadExecutionState(0) == ES_CONTINUOUS
。然而,假设当前线程设置了ES_SYSTEM_REQUIRED
,则SetThreadExecutionState(0) == ES_CONTINUOUS|ES_SYSTEM_REQUIRED
。如果函数失败,返回值不包含
ES_CONTINUOUS
,它将返回0
。据我所知,该函数可能失败的唯一方法是传递一些不受支持的标志。请注意,除了每个线程执行状态标志之外,还有系统范围的标志。您可以使用
CallNtPowerInformation< 获取这些信息/code>
与
SystemExecutionState
信息级别。如果任何线程具有SetThreadExecutionState(ES_CONTINUOUS|ES_SYSTEM_REQUIRED)
,则ES_SYSTEM_REQUIRED
将在SystemExecutionState
中设置。在我自己的测试中,其他每线程执行状态标志似乎都不会影响系统执行状态。SetThreadExecutionState
does two different things:It does (1) when you pass in
ES_CONTINUOUS
; otherwise it does (2).So, if you don't pass
ES_CONTINUOUS
as input, it will not change the current thread's execution flags, it will only reset idle timers.When resetting idle timers,
ES_SYSTEM_REQUIRED
tells it to reset the system idle timer, andES_DISPLAY_REQUIRED
tells it to reset the display idle timer. If you don't pass either ofES_SYSTEM_REQUIRED
orES_DISPLAY_REQUIRED
, it won't reset any idle timers.In other words,
SetThreadExecutionState(0)
is essentially a no-op – it doesn't change the thread's execution flags, nor does it reset any idle timers. But it does do something useful – it returns the current value of the thread execution flags.So, the
GetThreadExecutionState
you were looking for doesn't exist, but you don't need it, becauseSetThreadExecutionState(0)
is equivalent.Note that the return value always includes
ES_CONTINUOUS
. So, if your thread doesn't have any execution state flags set,SetThreadExecutionState(0) == ES_CONTINUOUS
. Whereas, suppose the current thread hasES_SYSTEM_REQUIRED
set, thenSetThreadExecutionState(0) == ES_CONTINUOUS|ES_SYSTEM_REQUIRED
.If the function fails, the return value doesn't include
ES_CONTINUOUS
, it will return0
. As far as I am aware, the only way the function can fail, is if you pass some unsupported flag.Note as well as the per-thread execution state flags, there are also system-wide flags. You can get those using
CallNtPowerInformation
withSystemExecutionState
information level. If any thread hasSetThreadExecutionState(ES_CONTINUOUS|ES_SYSTEM_REQUIRED)
, thenES_SYSTEM_REQUIRED
will be set in theSystemExecutionState
. In my own testing, none of the other per-thread execution state flags appear to impact the system execution state.