Windows核心编程:第5章 作业

Github

https://github.com/gongluck/Windows-Core-Program.git

//第5章 作业.cpp: 定义应用程序的入口点。
//

#include "stdafx.h"
#include "第5章 作业.h"

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    //在调试一个作业(Job)程序时发现,如下代码总是返回TRUE,无论是从VS中启动调试还是从资源管理器中启动。
    //原来,从资源管理器或者VS中启动程序时,系统会自动把该进程放到一个作业(Job)中。知道了这一点,要想让这段代码返回FALSE,只要从CMD中启动该程序即可。
    BOOL bInJob;
    IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);
    if (bInJob)
        MessageBox(nullptr, TEXT("process already in a job"), TEXT("info"), MB_OK);
    else
        MessageBox(nullptr, TEXT("process not in a job"), TEXT("info"), MB_OK);

    BOOL bret;
    HANDLE hJob = CreateJobObject(nullptr, TEXT("第5章 作业"));
    JOBOBJECT_BASIC_LIMIT_INFORMATION basiclimit = { 0 };
    //作业(进程沙盒)限制
    //JobObjectBasicLimitInformation、JobObjectExtendedLimitInformation、JobObjectBasicUIRestrictions、JobObjectSecurityLimitInformation
    //UserHandleGrantAccess授予或禁止一个Job中的进程访问施加了UI限制的用户对象的句柄的权限.当授予了访问权限,所有相关联的进程都可以在随后识别和使用这个句柄.当访问被拒绝,该进程不能在使用该句柄.
    basiclimit.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS | JOB_OBJECT_LIMIT_JOB_TIME;
    basiclimit.PriorityClass = IDLE_PRIORITY_CLASS;//指定关联进程的优先级类
    basiclimit.PerJobUserTimeLimit.QuadPart = 100000;//分配给进程的最大用户模式时间(100纳秒)
    bret = SetInformationJobObject(hJob, JobObjectBasicLimitInformation, &basiclimit, sizeof(basiclimit));
    bret = QueryInformationJobObject(hJob, JobObjectBasicLimitInformation, &basiclimit, sizeof(basiclimit), nullptr);
    JOBOBJECT_END_OF_JOB_TIME_INFORMATION endoftime;
    endoftime.EndOfJobTimeAction = JOB_OBJECT_POST_AT_END_OF_JOB;//到期不终止进程(If no completion port is associated with the job when the time limit has been exceeded, the action taken is the same as for JOB_OBJECT_TERMINATE_AT_END_OF_JOB。)JOB_OBJECT_TERMINATE_AT_END_OF_JOB(到期终止进程)
    bret = SetInformationJobObject(hJob, JobObjectEndOfJobTimeInformation, &endoftime, sizeof(endoftime));
    bret = QueryInformationJobObject(hJob, JobObjectEndOfJobTimeInformation, &endoftime, sizeof(endoftime), nullptr);

    //将进程放入作业中,只能添加未运行的“无业”进程
    STARTUPINFO si = { 0 };
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi = { 0 };
    bret = CreateProcess(TEXT("C:\\WINDOWS\\SYSTEM32\\NOTEPAD.EXE"), nullptr,  nullptr, nullptr, FALSE, CREATE_SUSPENDED, nullptr, nullptr, &si, &pi);
    bret = AssignProcessToJobObject(hJob, pi.hProcess);
    ResumeThread(pi.hThread);

    //查询作业(进程)统计信息
    JOBOBJECT_BASIC_ACCOUNTING_INFORMATION accountinfo = { 0 };
    bret = QueryInformationJobObject(hJob, JobObjectBasicAccountingInformation, &accountinfo, sizeof(accountinfo), nullptr);
    FILETIME c, e, k, u;
    bret = GetProcessTimes(pi.hProcess, &c, &e, &k, &u);
    JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION ioaccountinfo = { 0 };
    bret = QueryInformationJobObject(hJob, JobObjectBasicAndIoAccountingInformation, &ioaccountinfo, sizeof(ioaccountinfo), nullptr);
    IO_COUNTERS ioconters;
    bret = GetProcessIoCounters(pi.hProcess, &ioconters);

    //查询作业内进程
    const int max = 10;
    DWORD cb = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + (max - 1) * sizeof(ULONG_PTR);
    PJOBOBJECT_BASIC_PROCESS_ID_LIST pidlist = (PJOBOBJECT_BASIC_PROCESS_ID_LIST)malloc(cb);
    pidlist->NumberOfAssignedProcesses = max;
    bret = QueryInformationJobObject(hJob, JobObjectBasicProcessIdList, pidlist, cb, &cb);
    for (int i = 0; i < pidlist->NumberOfProcessIdsInList; ++i)
    {
        pidlist->ProcessIdList[i];
    }
    free(pidlist);
    pidlist = nullptr;

    //已分配的CPU时间到期时,作业状态变成已触发
    WaitForSingleObject(hJob, INFINITE);

    system("pause");

    //终止作业中所有的进程
    bret = TerminateJobObject(hJob, 0);

    CloseHandle(pi.hProcess);
    pi.hProcess = nullptr;
    CloseHandle(pi.hThread);
    pi.hThread = nullptr;
    system("pause");
    return 0;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏乐沙弥的世界

又一例SPFILE设置错误导致数据库无法启动

--========================================

653
来自专栏纯洁的微笑

jvm系列(五):Java GC 分析

Java GC就是JVM记录仪,书画了JVM各个分区的表演。 什么是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)...

3494
来自专栏文渊之博

孤立的SQL用户

问题 最近公司很多数据库在上云,也有一部分在下云。这期间出现了很多问题,其中一个比较恶心的问题就是“孤立用户”。当数据库备份还原以后用以前的用户发现不能登录。一...

3287
来自专栏北京马哥教育

通过IP获取地理位置信息的几种方式

1、QQWry IP纯真数据库 纯真版IP地址数据库是当前网络上最权威、地址最精确、IP记录以及网吧数据最多的IP地址数据库。收集了包括中国电信、中国移动、中...

3715
来自专栏公有云大数据平台弹性MapReduce

Hbase Region Split compaction 过程分析以及调优

Hbase以高并发写入而闻名,而Compact和Split功能贯穿了hbase的整个写入过程,而只有掌握了Compact和Split内部逻辑以及控制参数才能根据...

1.3K0
来自专栏乐沙弥的世界

ORA-02409:超时:分布式事务处理等待锁定ORA-02063

ORA-02409:超时:分布式事务处理等待锁定ORA-02063 一、错误现象与环境     前端应用程序运行时出现下面的错误提示: 事件添加失败:O...

822
来自专栏施炯的IoT开发专栏

移动物联网 之 家电节能 (2)

    本系列文章结合时下正热的“物联网”概念,介绍实现“家电节能”的一套解决方案。本部分讲述 “家电节能”的具体实现方法。 1. 系统结构 系统包括Senso...

1817
来自专栏安富莱嵌入式技术分享

【二代示波器教程】第14章 uCOS-III操作系统版本二代示波器实现

本章教程为大家讲解uCOS-III操作系统版本的二代示波器实现。主要讲解RTOS设计框架,即各个任务实现的功能,任务间的通信方案选择,任务栈,系统栈以及全局变量...

905

Cassandra的数据布局 - 调试SSTables

当您事先知道数据的格式并且可以基于过往的经验做决策时,使用Apache Cassandra处理大规模的该类型的数据是非常容易的。

3220
来自专栏c#开发者

MSMQ消息大于4MB限制的解决办法

MSMQ 消息发送大于 4 导致 System.Messaging.MessageQueueException Mb。 察看本文应用于的产品 社区解决方案免责...

33813

扫码关注云+社区