- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
Windows 8/10 中的 UWP(或“Metro”)应用程序不在前台时可以暂停。处于此状态的应用程序继续存在但不再消耗 CPU 时间。引入此更改似乎是为了提高平板电脑和手机等低功耗/存储设备的性能。
检测处于这种状态的进程的最优雅、最简单的方法是什么?
目前我可以看到 2 种可能的解决方案:
调用 NtQuerySystemInformation() 并枚举每个进程和每个线程。如果所有线程都处于挂起状态,则进程被“挂起”。这种方法将需要大量代码,而且关键的是 NtQuerySystemInformation() 只是半文档化的,可能会在未来的操作系统中被删除。 NtQueryInformationProcess() 也可能针对相同的问题提供类似的解决方案。
调用 GetProcessTimes() 并记录每个进程的计数器。等待一些较长的时间(分钟)并再次检查。如果进程计数器未更改,则假定进程已挂起。我承认这是一个 hack,但如果时间足够长,可能会奏效。
有没有更优雅的方式?
最佳答案
为此存在PROCESS_EXTENDED_BASIC_INFORMATION
- 本answer中描述的标志的含义.你需要 IsFrozen
标志。因此您需要具有 PROCESS_QUERY_LIMITED_INFORMATION
访问权限的开放进程(要对所有进程执行此操作,您需要在 token 中启用 SE_DEBUG_PRIVILEGE
)。并使用 ProcessBasicInformation
和 PROCESS_EXTENDED_BASIC_INFORMATION
调用 NtQuerySystemInformation
作为输入。为了枚举所有进程,我们可以使用 NtQuerySystemInformation
和 SystemProcessInformation
。当然可以并使用 CreateToolhelp32Snapshot
+ Process32First
+ Process32Next
但是这个 api 效率很低,比较直接调用 NtQuerySystemInformation
也可以枚举进程中的所有线程并检查它的状态,如果状态等待 - 等待原因。这非常简单,因为所有这些信息都已经通过使用 SystemProcessInformation
调用 NtQuerySystemInformation
返回了。有了这个,我们就不需要开放流程了。通常这两种方式都会给出相同的结果(对于暂停/卡住)进程,但是使用 IsFrozen
是最正确的解决方案。
void PrintSuspended()
{
BOOLEAN b;
RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &b);
ULONG cb = 0x1000;
NTSTATUS status;
do
{
status = STATUS_INSUFFICIENT_RESOURCES;
if (PBYTE buf = new BYTE[cb])
{
if (0 <= (status = NtQuerySystemInformation(SystemProcessInformation, buf, cb, &cb)))
{
union {
PBYTE pb;
SYSTEM_PROCESS_INFORMATION* spi;
};
pb = buf;
ULONG NextEntryOffset = 0;
do
{
pb += NextEntryOffset;
if (!spi->UniqueProcessId)
{
continue;
}
if (HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
(ULONG)(ULONG_PTR)spi->UniqueProcessId))
{
PROCESS_EXTENDED_BASIC_INFORMATION pebi;
if (0 <= NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pebi, sizeof(pebi), 0) &&
pebi.Size >= sizeof(pebi))
{
if (pebi.IsFrozen)
{
DbgPrint("f:%x %wZ\n", spi->UniqueProcessId, spi->ImageName);
}
}
CloseHandle(hProcess);
}
if (ULONG NumberOfThreads = spi->NumberOfThreads)
{
SYSTEM_THREAD_INFORMATION* TH = spi->TH;
do
{
if (TH->ThreadState != StateWait || TH->WaitReason != Suspended)
{
break;
}
} while (TH++, --NumberOfThreads);
if (!NumberOfThreads)
{
DbgPrint("s:%x %wZ\n", spi->UniqueProcessId, spi->ImageName);
}
}
} while (NextEntryOffset = spi->NextEntryOffset);
}
delete [] buf;
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
}
关于windows - 检测 "suspended"Windows 8/10 进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50172564/
C++ 社区目前正在讨论上挂协程与下挂协程。 例如,这个提案中提到了挂起:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4453.p
我刚刚在稳定 channel 上升级了 Flutter,并在尝试启动应用程序(在本地 iOS 模拟器上)时获得了以下 StackTrace。使用 flutter test 运行单元测试也会受到影响。
我想使用插件camera_camera。但是当我尝试编译项目时出现此错误: Flutter:错误:找不到 Getter:“正在暂停”。案例 AppLifecycleState.suspending。
我正在考虑有关 suspend 的事情Arrow 的文档详细解释了:suspend () -> A提供与 IO 相同的保证. 因此,根据文档,只需使用 suspend我们正在将不纯函数转换为纯函数:
Grails应用程序在启动时会以--debug-forked模式挂起。 我正在使用--debug-fork参数运行应用程序,但它会挂起并等待,直到调试器连接到它,然后调试器断开连接,应用程序再次等待调
请考虑以下代码: // program is reading data from an excel file, Sheet1 at cell(0,0). public class Read {
Windows 和 Solaris 线程 API 都允许在“暂停”状态下创建线程。线程仅在稍后“恢复”时才真正开始。我习惯了没有这个概念的 POSIX 线程,我正在努力理解它的动机。谁能建议为什么创建
将方法注释为 @Suspendable 的最佳实践是什么?在 Flow 中,可能有多个查询 vault/compute 业务逻辑的私有(private)方法。这些是否应该用 @Suspendable
有没有办法暂时暂停表单上所有锚定控件的移动或调整大小?即: procedure ScaleFormBy(AForm: TForm; n, d: Integer); begin AForm.Su
我一直在尝试追踪 Jedi VCL 的 JvHidControllerClass.pas 中的内存泄漏,我在源代码历史记录中发现了此更改: 旧版本: constructor TJvHidDeviceR
我正在制作具有过渡-缩放-平移-效果的幻灯片,其性能对于平滑渲染至关重要。这是一个我要移植到Delphi 10.3的旧项目,有一个线程可以在运行渲染到屏幕的同时从jpgeg-images的文件流中加载
我需要在用户继续使用它的同时调试生产服务器。当断点命中时,我希望为其他用户的请求提供服务的其他线程在我检查线程中的变量并决定跳过或进入方法时继续工作。 在 Java 中,当遇到断点时,您可以在“暂停线
大家好我在做秒表。对于暂停,我使用 Thread.suspend() ,对于恢复,我使用 Thread.resume()。但简历并不是恢复工作。代码: pause(){ shouldRun = f
有一个程序在 TCP/IP 端口中监听和应答请求(专有二进制协议(protocol))。但该程序需要更新,因此需要重新启动,然后才能继续在同一端口上执行其工作。 根据其协议(protocol),所有当
这个问题与 Thread.suspend 的替代方案无关。这是关于使用 Thread.suspend 实现偏向锁的可能性,(我相信)不能使用 Thread.interrupt 或类似的替代方案来实现。
所以我已经启动并运行了一台家庭服务器,并使用局域网唤醒对其进行了设置,并且有一位 friend 设法将其从两个州之外的地方唤醒。太棒了,这样我就可以运行文件服务器而无需一直保持开机状态。问题是,唤醒它
有没有办法确定是否已注册指纹但 Touch ID 由于指纹验证失败次数过多而当前处于“暂停”状态? 最佳答案 错误代码可以与 LAError 类进行比较。 func errorMessageForLA
一般问题... 如果我在我的 VBA 代码(基于 Excel)中暂停/退出/中断“For”循环,会有什么危险? 这是我的代码: For i = 1 to Sheets.Count 'check
我有一个 WPF 项目,当我尝试在 RowLoad 事件上运行此代码时,出现以下错误: private void ParentGridView_OnRowLoaded(object sender, E
在我的帐户页面/查看订阅中,在 ACTION 段落中,我有一个 CANCEL 按钮,但没有 SUSPEND 按钮。你知道这是否正常吗? 我跟踪了这个函数,它只返回取消数据:wcs_get_all_
我是一名优秀的程序员,十分优秀!