您的位置:首页 > 编程语言

Windows编程基础 第十四章 进程 作业 线程 线程局部存储

2014-09-12 18:26 471 查看
本文是截图: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;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: