本文是截图:Windows编程基础 第十四章 进程 作业 线程 线程局部存储
本文的pdf下载地址是:http://yunpan.cn/cdngGRyIvS4a4 访问密码 b059
// 本程序演示系统环境信息的获取,环境变量的设置和获取
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "locale.h"
#define MAX_LENGTH 1024
/*
GetEnvironmentStrings()
FreeEnvironmentStrings()
GetEnvironmentVariable()
setenvironmentv()
*/
VOID EnvVariable(TCHAR * pszVar)
{
SetEnvironmentVariable(pszVar,TEXT("C:\\"));//参数一:The name of the environment variable.参数二:The contents of the environment variable.
TCHAR szValue[MAX_LENGTH]={0};
GetEnvironmentVariable(pszVar,szValue,MAX_LENGTH);
_tprintf(TEXT("%s=%s"),pszVar,szValue);
}
VOID EnvString()
{
TCHAR * pszEnv=GetEnvironmentStrings();//取得系统环境信息,返回一个字符串的串
TCHAR * pszTmp=pszEnv;
while (pszTmp[0]!=0)
{
_tprintf(TEXT("%s\n"),pszTmp);
pszTmp=_tcslen(pszTmp)+1+pszTmp;
}
FreeEnvironmentStrings(pszEnv);//释放环境信息
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"zhi");
_tprintf(TEXT("取得的系统信息如下:\n"));
EnvString();
_tprintf(TEXT("-------------------------------------------\n"));
EnvVariable(TEXT("MYPATH"));
_tprintf(TEXT("\n-------------------------------------------\n"));
return 0;
}
// 本程序用来演示基本的进程信息和PSAPI这个WIN NT扩展库的使用
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "locale.h"
#include "../psapi/PSAPI.H" //加载process status API库的头文件
#pragma comment(lib,"../psapi/psapi.lib")//隐式加载process status API动态库
VOID ProcModule()
{
//枚举当前进程的所有的模块
_tprintf(TEXT("All Modules:\n"));
HANDLE hProc=GetCurrentProcess();//取得当前进程的伪句柄。
/*
BOOL WINAPI EnumProcessModules(
__in HANDLE hProcess,
__out HMODULE *lphModule,
__in DWORD cb,//The size of the lphModule array, in bytes.注意是字节数
__out LPDWORD lpcbNeeded//The number of bytes required to store all module handles in the lphModule array.注意也是字节数
);
*/
HMODULE hModule[260]={0};//定义一个模块数组,作为EnumProcessModules()的出参。
DWORD nWriteCount=0;//返回写入的模块的数量
EnumProcessModules(hProc,hModule,260,&nWriteCount);//枚举进程的所有的模块
DWORD nSize=sizeof(HMODULE);//4个字节
DWORD nCount=nWriteCount/nSize;//100字节/4字节
for (int nIndex=0;nIndex<nCount;nIndex++)
{
TCHAR szPath[260]={0};
GetModuleFileNameEx(hProc,hModule[nIndex],szPath,260);//通过模块句柄返回模块的名字
_tprintf(TEXT("\t%d:%p=%s\n"),nIndex+1,hModule[nIndex],szPath);//0x 00 d0 00 00 4个字节
}
}
VOID ProcInfo()
{
//获取进程的ID
DWORD nID=GetCurrentProcessId();
//获取进程的伪句柄
HANDLE hProc=GetCurrentProcess();
_tprintf(TEXT("\n\t当前的进程ID是:%d,进程的伪句柄的数值是:%p\n"),nID,hProc);//hProc的十六进制数值是FFFFFFFF十进制数值是-1。
hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,nID);//通过指定的进程ID获取进程的句柄。
_tprintf(TEXT("\t当前进程的真正的句柄是:%p\n\n"),hProc);
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"zhi");
ProcModule();
ProcInfo();
return 0;
}
//本程序用来演示进程的创建,销毁,等待
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "locale.h"
VOID CreateProcess()
{
/*
BOOL WINAPI CreateProcess(
__in_opt LPCTSTR lpApplicationName,
__inout_opt LPTSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCTSTR lpCurrentDirectory,
__in LPSTARTUPINFO lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);
*/
STARTUPINFO start_info={0};
start_info.cb=sizeof(STARTUPINFO);
start_info.dwFlags= STARTF_USESIZE|STARTF_USESTDHANDLES;//如果想要使用下面的两个参数调整窗口的大小,那么一定要指定这个标示
start_info.dwXSize=300;//通过下面的两个参数调整窗口的大小
start_info.dwYSize=300;
PROCESS_INFORMATION Process_info={0};
//创建进程,但是无法创建,因为DOS方式的控制台的16位程序必须使用第二个参数所以这句执行之后是看不到,ChildProc.exe程序运行的
//CreateProcess(TEXT("C:\\ChildProc.exe"),TEXT("\"Hello Child\""),NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&start_info,&Process_info);
CreateProcess(NULL,TEXT("C:\\ChildProc.exe"),NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&start_info,&Process_info);
//这个函数在VC++6.0 XP环境下运行成功,但是WIN7 VS2010不行
//数据进程的相关的信息
_tprintf(TEXT("进程的句柄是:%p\n"),Process_info.hProcess);
_tprintf(TEXT("进程的ID是:%d\n"),Process_info.dwProcessId);
_tprintf(TEXT("线程的句柄是:%p\n"),Process_info.hThread);
_tprintf(TEXT("线程的ID是:%d\n"),Process_info.dwThreadId);
}
VOID TerminateProc(DWORD nID)
{
//根据进程的ID获取进程的句柄
HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,nID);
//终止进程
TerminateProcess(hProc,0);
}
VOID WaitProcess()
{
//创建进程
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof( si );//这个参数是必须进行赋值的,原因好像在windows核心编程中讲过,但是我忘记了
CreateProcess( TEXT("C:\\MineSweeper.exe"),NULL, NULL, NULL, FALSE, 0,NULL, NULL, &si, &pi );
_tprintf(TEXT("扫雷程序正在运行!\n"));
WaitForSingleObject(pi.hProcess,9000000);
_tprintf(TEXT("扫雷程序结束运行!\n"));
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"zhi");
CreateProcess();
//TerminateProc( 5368 );//结束一个进程,当前任务管理器中的这个进程是QQ
//WaitProcess();
return 0;
}
下面的两个程序功能是一样的,代码基本上是一样的。都是创建一个作业然后在作业中添加了两个进程,我们对作业进行了功能的限制,限制在作业中的进程都不能使用剪切板的功能,但是我们惊奇的发现同样的程序在 WIN7 操作系统上,使用VS2010 和 在XP操作系统上使用 VC++6.0 代码运行之后出现的效果是完全不同的。
我们在VC++6.0上程序运行的时候,完全能够实现限制剪切板的操作。也就是剪切板不能使用,进行复制和黏贴的操作。但是同样的程序在VS2010下执行的时候,剪切板的功能竟然能够使用!!!!!!具体的原因到现在还有找到。。。。。找到之后再记录下来。
//本程序用来演示作业的使用 在WIN7系统和VS2010编译环境下运行。无法实现限制剪切板的功能
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "locale.h"
HANDLE Create(TCHAR * szPath)//根据指定的引用程序名字创建一个进程,然会返回进程的句柄
{
STARTUPINFO si={0};
PROCESS_INFORMATION pi={0};
si.cb=sizeof(STARTUPINFO);
CreateProcess(szPath,NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
return pi.hProcess;
}
VOID Job()
{
//创建Job对象
HANDLE hJob = CreateJobObject( NULL,TEXT( "MyJob") );
//设置权限
JOBOBJECT_BASIC_UI_RESTRICTIONS ui = {0};
ui.UIRestrictionsClass = JOB_OBJECT_UILIMIT_READCLIPBOARD|JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
SetInformationJobObject( hJob,JobObjectBasicUIRestrictions,&ui,sizeof(ui));
//创建进程
HANDLE hProc =Create(TEXT("c:\\mspaint.exe" ));
//将进程加入作业
AssignProcessToJobObject(hJob, hProc);
hProc=Create(TEXT("c:\\mspaint.exe"));
AssignProcessToJobObject(hJob, hProc );
getchar( );
//结束作业
TerminateJobObject( hJob, 0 );
//关闭Job
CloseHandle( hJob );
}
int _tmain(int argc, _TCHAR* argv[])
{
Job();
return 0;
}
// 本程序在XP操作系统上,使用VC++6.0环境,我们可以看到程序能实现限制画图程序的剪切板的使用的功能
//本程序运行的时候需要在stdafx.cpp文件中添加宏定义:#define _WIN32_WINNT 0X0500
//本程序用来演示作业的使用
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "locale.h"
HANDLE Create(TCHAR * szPath)//根据指定的引用程序名字创建一个进程,然会返回进程的句柄
{
STARTUPINFO si={0};
PROCESS_INFORMATION pi={0};
si.cb=sizeof(STARTUPINFO);
CreateProcess(szPath,NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
return pi.hProcess;
}
VOID Job()
{
//创建Job对象
HANDLE hJob = CreateJobObject( NULL,TEXT( "MyJob") );
//设置权限
JOBOBJECT_BASIC_UI_RESTRICTIONS ui = {0};
ui.UIRestrictionsClass = JOB_OBJECT_UILIMIT_READCLIPBOARD|JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
SetInformationJobObject( hJob,JobObjectBasicUIRestrictions,&ui,sizeof(ui));
//创建进程
HANDLE hProc =Create(TEXT("C:\\mspaint.exe" ));
//将进程加入作业
AssignProcessToJobObject(hJob, hProc);
hProc=Create(TEXT("C:\\mspaint.exe"));
AssignProcessToJobObject(hJob, hProc );
getchar( );
//结束作业
TerminateJobObject( hJob, 0 );
//关闭Job
CloseHandle( hJob );
}
int _tmain(int argc, _TCHAR* argv[])
{
Job();
return 0;
}
//本程序用来演示进程的创建,销毁,等待
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "locale.h"
VOID CreateProcess()
{
/*
BOOL WINAPI CreateProcess(
__in_opt LPCTSTR lpApplicationName,
__inout_opt LPTSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCTSTR lpCurrentDirectory,
__in LPSTARTUPINFO lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);
*/
STARTUPINFO start_info={0};
start_info.cb=sizeof(STARTUPINFO);
start_info.dwFlags= STARTF_USESIZE|STARTF_USESTDHANDLES;//如果想要使用下面的两个参数调整窗口的大小,那么一定要指定这个标示
start_info.dwXSize=300;//通过下面的两个参数调整窗口的大小
start_info.dwYSize=300;
PROCESS_INFORMATION Process_info={0};
//创建进程,但是无法创建,因为DOS方式的控制台的16位程序必须使用第二个参数所以这句执行之后是看不到,ChildProc.exe程序运行的
//CreateProcess(TEXT("C:\\ChildProc.exe"),TEXT("\"Hello Child\""),NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&start_info,&Process_info);
CreateProcess(NULL,TEXT("C:\\ChildProc.exe"),NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&start_info,&Process_info);
//这个函数在VC++6.0 XP环境下运行成功,但是WIN7 VS2010不行
//数据进程的相关的信息
_tprintf(TEXT("进程的句柄是:%p\n"),Process_info.hProcess);
_tprintf(TEXT("进程的ID是:%d\n"),Process_info.dwProcessId);
_tprintf(TEXT("线程的句柄是:%p\n"),Process_info.hThread);
_tprintf(TEXT("线程的ID是:%d\n"),Process_info.dwThreadId);
}
VOID TerminateProc(DWORD nID)
{
//根据进程的ID获取进程的句柄
HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,nID);
//终止进程
TerminateProcess(hProc,0);
}
VOID WaitProcess()
{
//创建进程
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof( si );//这个参数是必须进行赋值的,原因好像在windows核心编程中讲过,但是我忘记了
CreateProcess( TEXT("C:\\winmine.exe"),NULL, NULL, NULL, FALSE, 0,NULL, NULL, &si, &pi );
_tprintf(TEXT("扫雷程序正在运行!\n"));
WaitForSingleObject(pi.hProcess,INFINITE);
_tprintf(TEXT("扫雷程序结束运行!\n"));
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"zhi");
// CreateProcess();
//TerminateProc( 5368 );//结束一个进程,当前任务管理器中的这个进程是QQ
WaitProcess();
return 0;
}
// 本程序用来演示线程的创建和使用
//
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "locale.h"
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
DWORD nValue=(DWORD)lpParameter;//把传递进来的数值强制类型转换成为一个DWORD类型的数值
for (int nIndex=0;nIndex<10;nIndex++)
{
_tprintf(TEXT("线程一 --------------%d\n"),nValue);
Sleep(1000);
}
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
while(1)
{
_tprintf(TEXT("----------------------线程二\n"));
Sleep(1000);
}
return 0;
}
VOID Create()
{
DWORD nValue=100;
DWORD nThreadId=0;
//创建一个挂起的线程
HANDLE hThread=CreateThread(NULL,0,ThreadProc1,(LPVOID)nValue,CREATE_SUSPENDED,&nThreadId);
_tprintf(TEXT("线程1的线程ID:%d\n"),nThreadId);
_tprintf(TEXT("线程1的线程句柄是:%p\n"),hThread);
ResumeThread(hThread);//恢复线程使线程开始运行。
WaitForSingleObject(hThread,INFINITE);//等候线程1的运行的结束
CloseHandle(hThread);
hThread=CreateThread(NULL,0,ThreadProc2,NULL,0,&nThreadId);
_tprintf(TEXT("线程2的线程ID:%d\n"),nThreadId);
_tprintf(TEXT("线程2的线程句柄是:%p\n"),hThread);
//挂起线程
//SuspendThread(hThread);
//WaitForSingleObject(hThread,INFINITE);//没有这条语句,我们会看不到线程2的执行,会值打印出线程2的ID就结束了。
CloseHandle(hThread);
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"zhi");
Create();
return 0;
}
<pre name="code" class="cpp">// 线程局部存储TLS
//
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "locale.h"
TCHAR * g_pszText1=NULL;
__declspec(thread) TCHAR * g_pszText2=NULL;
VOID Print( )
{
_tprintf(TEXT("Text1:%s\n"),g_pszText1);
//_tprintf(TEXT("Text2:%s\n"),g_pszText2);
}
DWORD WINAPI PrintProc( LPVOID lpParameter)
{
TCHAR * pszText=(TCHAR *) lpParameter;
g_pszText1=(TCHAR *)malloc(100);
memset(g_pszText1,0,100);
_tcscpy(g_pszText1,pszText);
g_pszText2=(TCHAR *)malloc(100);
memset(g_pszText2,0,100);
_tcscpy(g_pszText2,pszText);
while(1)
{
Print();
Sleep(1000);
}
return 0;
}
VOID Create()
{
DWORD dwThread=0;
TCHAR szText1[]=TEXT("线程1-------------------");
HANDLE hThread=CreateThread(NULL,0,PrintProc,szText1,0,&dwThread);
TCHAR szText2[]=TEXT("-----------线程2--------");
hThread=CreateThread(NULL,0,PrintProc,szText2,0,&dwThread);
TCHAR szText3[]=TEXT("-------------------线程3");
hThread=CreateThread(NULL,0,PrintProc,szText3,0,&dwThread);
getchar();//这个getchar()必须放在Create()函数中,而不能放在main()函数中。否则会出现乱码因为szText[]都是局部变量。
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"chs");
Create();
return 0;
}