• Windows核心编程笔记之进程


    • 改变进程基址,获取进程基址
    #include <Windows.h>
    #include <iostream>
    #include <strsafe.h>
    #include <STDLIB.H>
    using namespace std;
    
    #pragma comment(linker, "/BASE:0x400000") // 改变进程加载机地址
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	WCHAR RouteBuffer[60] = { 0 };
    	DWORD res = GetModuleFileName(NULL, RouteBuffer, sizeof(RouteBuffer)); // 获取当前程序的全路径
    	WCHAR AfterVersion[130] = { 0 };
    	HMODULE EBAddress = GetModuleHandle(TEXT("NpCxyFW.exe")); // 获取当前进程的句柄 / 基址
    	StringCchPrintf(AfterVersion, sizeof(AfterVersion) / 2, 
    		TEXT("程序全路径: %s
    hInstance获取到的程序基址: %x 
    GetModuleHandle获取到的程序基址: %x"), 
    		RouteBuffer, hInstance, EBAddress
    	);
    	INT Box_1 = MessageBox(NULL, AfterVersion, TEXT("测试"), MB_OKCANCEL);
    	return 0;
    }
    

    在这里插入图片描述

    • 通过 GetCommandLine() 获取命令行参数
    #include <Windows.h>
    #include <iostream>
    #include <strsafe.h>
    using namespace std;
    
    int main(int argc, char *argv[])
    { 
    	// 通过 GetCommandLine 获取命令行参数
    	INT CmdCount = NULL;
    	PWSTR *CmdLine = CommandLineToArgvW(GetCommandLine(), &CmdCount);
    	for (size_t i = 1; i < CmdCount; i++)
    	{	
    		WCHAR *BeforeConversion = CmdLine[i]; CHAR AfterConversion[20] = { 0 }; 
    		// 将宽字节字符转换为多字节字符
    		int res = WideCharToMultiByte(CP_UTF8, NULL, BeforeConversion, -1, AfterConversion, sizeof(AfterConversion), NULL, NULL);
    		cout << "参数 " << i << ": "<< AfterConversion << endl;
    	}
    	return 0;
    }
    

    在这里插入图片描述

    • 显示进程环境块
    #include <Windows.h>
    #include <iostream>
    #include <wcschr.h>  
    #include <strsafe.h>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
    	PTSTR PEnvBlock = GetEnvironmentStrings();				// 获取进程环境块,也可以使用 int main(TCHAR *env[]) 的方式获取
    
    	TCHAR SzName[MAX_PATH]; TCHAR SzValue[MAX_PATH];
    	PTSTR PszCurrent = PEnvBlock;
    	HRESULT hr = S_OK; PCTSTR PszPos = NULL; int current = 0;
    
    	while (PszCurrent != NULL) {														
    		if (*PszCurrent != TEXT('=')) {													// 若第一个字符不是 '='
    			PszPos = _tcschr(PszCurrent, TEXT('='));  PszPos++;							// 查找 '=' 在字符串中的位置
    			size_t cbNameLength = (size_t)PszPos - (size_t)PszCurrent - sizeof(TCHAR);  // 获取 Name 字段的长度
    			hr = StringCbCopyN(SzName, MAX_PATH, PszCurrent, cbNameLength);             // 将 Name 字段拷贝到 szName 中
    			if (FAILED(hr)) break;
    
    			hr = StringCchCopyN(SzValue, MAX_PATH, PszPos, _tcslen(PszPos) + 1);	// 将 '=' 字符之后的内容拷贝至 szValue 中
    			if (SUCCEEDED(hr))
    			{
    				_tprintf(TEXT("[%u] %s=%s
    "), current, SzName, SzValue);			// 成功便打印出信息
    			}
    			else
    			{
    				if (hr == STRSAFE_E_INSUFFICIENT_BUFFER)							// 错误处理,STRSAFE_E_INSUFFICIENT_BUFFER 缓冲区空间不足
    					_tprintf(TEXT("[%u] %s=%s...
    "), current, SzName, SzValue);
    				else
    					_tprintf(TEXT("[%u] %s=???
    "), current, SzName); break;
    			}
    		}
    		else {	
    			_tprintf(TEXT("[%u] %s
    "), current, PszCurrent);  // 若一开始就为 '=' 字符,就直接打印出字符串的内容
    		}
    		current++;										 // 环境变量的个数加 1
    		while (*PszCurrent != TEXT('')) PszCurrent++;  // 移动到字符串的结尾
    		PszCurrent++;									 // 跳过 ''
    		if (*PszCurrent == TEXT('')) break;			 // 检查它是否不是最后一个字符串
    	};
    	FreeEnvironmentStrings(PEnvBlock);					 //释放空间
    	return 0;
    }
    
    
    • 获得某个环境变量
    #include <Windows.h>
    #include <iostream>
    #include <strsafe.h>
    #include <stdio.h>
    using namespace std;
    
    int main(TCHAR *env[])
    {
    	PWSTR lpBuffer = NULL;
    	DWORD Size = GetEnvironmentVariable(TEXT("PATH"), lpBuffer, 0); // 首先判断是否存在 PATH 环境变量
    	if (Size != 0)
    	{
    		DWORD BufferSize = Size * sizeof(TCHAR);
    		lpBuffer = (PWSTR)malloc(BufferSize);		// 存在即分配缓冲区空间
    		GetEnvironmentVariable(TEXT("PATH"), lpBuffer, BufferSize);
    		printf("%ls", lpBuffer);					// 打印 PATH 环境变量的信息
    	}
    	return 0;
    }
    
    • 获取当前目录
    #include <Windows.h>
    #include <iostream>
    #include <stdio.h>
    #include <versionhelpers.h>
    using namespace std;
    
    BOOL CompareOS(INT dwMajorVersion, INT dwMinorVersion);
    
    int main(TCHAR *env[])
    {
    	// 获取当前目录方法 1
    	TCHAR Buffer_1[MAX_PATH] = { 0 };
    	DWORD DirLength = GetCurrentDirectory(MAX_PATH, Buffer_1);
    	printf("目录: %ls
    ", Buffer_1);
    	// 获取当前目录方法 2
    	TCHAR Buffer_2[MAX_PATH];
    	DWORD PathLength = GetFullPathName(TEXT("C:"), MAX_PATH, Buffer_2, NULL);
    	printf("目录: %ls
    ", Buffer_2);
    
    	return 0;
    }
    
    
    • 判断系统版本号的两种方法
    VOID JudgeOS() // 通过 VerifyVersionInfo 比较判断,准确度一般
    {
    	if (!CompareOS(10, 0))
    		if (!CompareOS(6, 3))
    			if (!CompareOS(6, 2))
    				if (!CompareOS(6, 1))
    					if (!CompareOS(6, 0))
    						if (!CompareOS(5, 2))
    							if (!CompareOS(5, 1))
    								if (!CompareOS(5, 0))
    									cout << "未知的操作系统版本" << endl;
    								else
    									cout << "版本在 Window2000 以上" << endl;
    							else
    								cout << "版本在 Windows XP 以上" << endl;
    						else
    							cout << "版本在 Windows XP Professional x64 Edition 以上" << endl;
    					else
    						cout << "版本在 Windows Vista 或者 Windows Server 2008 以上" << endl;
    				else
    					cout << "版本在 Windows 7 或者 Windows Server 2008 R2 以上" << endl;
    			else
    				cout << "版本在 Windows 8 或者 Windows Server 2012 以上" << endl;
    		else
    			cout << "版本在 Windows 8.1 或者 Windows Server 2012 R2 以上" << endl;
    	else
    		cout << "版本在 Windows Server 2016 或者 Windows 10 以上" << endl;
    }
    
    BOOL CompareOS(INT MajorVersion, INT MinorVersion)
    {
    	OSVERSIONINFOEX OSinfo = { 0 };
    	OSinfo.dwOSVersionInfoSize = sizeof(OSinfo);
    	OSinfo.dwMajorVersion = MajorVersion; OSinfo.dwMinorVersion = MinorVersion; // 设置比较操作系统版本的区间组合
    	
    	DWORDLONG dwlConditionMask = 0;			// 设置用于比较操作系统的宏
    	VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL); 
    	VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL);
    
    	BOOL Res = VerifyVersionInfo(&OSinfo, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask); // 第二个参数为比较位,支持 or 操作
    	return Res;		// 函数成功返回非 0 值
    }
    
    #include <Windows.h>
    #include <iostream>
    #include <stdio.h>
    #include <versionhelpers.h>
    using namespace std;
    // 利用官方的便捷函数进行操作系统的判别
    INT JudgeOS();
    
    int main(TCHAR *env[])
    {
    	JudgeOS(); // 打印操作系统版本的信息
    	return 0;
    }
    
    INT JudgeOS()
    {
    	if (IsWindowsServer())
    		cout << "操作系统是服务器" << endl;
    	else
    		if (!IsWindows10OrGreater())
    			if (!IsWindows8OrGreater())
    				if (!IsWindows7SP1OrGreater())
    					if (!IsWindows7OrGreater())
    						if (!IsWindowsVistaSP2OrGreater())
    							if (!IsWindowsVistaSP1OrGreater())
    								if (!IsWindowsVistaOrGreater())
    									if (!IsWindowsXPSP3OrGreater())
    										if (!IsWindowsXPSP2OrGreater())
    											if (!IsWindowsXPSP1OrGreater())
    												if (!IsWindowsXPOrGreater())
    													cout << "未知的操作系统版本" << endl;
    												else
    													cout << "当前操作系统版本是否与Windows XP版本匹配或大于Windows XP版本 " << endl;
    											else
    												cout << "当前操作系统版本是否与Windows XP Service Pack 1(SP1)版本匹配或大于" << endl;
    										else
    											cout << "当前操作系统版本是否与Windows XP Service Pack 2(SP2)版本匹配或大于" << endl;
    									else
    										cout << "当前操作系统版本是否与Windows XP Service Pack 3(SP3)版本匹配或大于" << endl;
    								else
    									cout << "当前操作系统版本是否与Windows Vista版本匹配或大于Windows Vista版本" << endl;
    							else
    								cout << "当前操作系统版本是否与Windows Vista Service Pack 1(SP1)版本匹配或大于" << endl;
    						else
    							cout << "当前操作系统版本是否与Windows Vista Service Pack 2(SP2)版本匹配或大于" << endl;
    					else
    						cout << "当前操作系统版本是否与Windows 7版本匹配或大于Windows 7版本" << endl;
    				else
    					cout << "当前操作系统版本是否与Windows 7 Service Pack 1(SP1)版本匹配或大于" << endl;
    			else
    				cout << "当前操作系统版本是否与Windows 8版本匹配或大于Windows 8版本" << endl;
    		else
    			cout << "指示当前操作系统版本是否与Windows 10版本匹配或大于Windows 10版本" << endl;
    	return 0;
    }
    
    • 进程创建
    #include <Windows.h>
    #include <iostream>
    #include <stdio.h>
    #include <versionhelpers.h>
    using namespace std;
    
    int main(TCHAR *env[])
    {
    	DWORD ExitCode = NULL;
    
    	// 创建线程和进程的安全结构体
    	SECURITY_ATTRIBUTES ProcessSec = { 0 };  SECURITY_ATTRIBUTES ThreadSec = { 0 };
    	ProcessSec.nLength = sizeof(ProcessSec); ThreadSec.nLength = sizeof(ThreadSec);
    	ProcessSec.bInheritHandle = TRUE;	     ThreadSec.bInheritHandle = TRUE;			  // 指定线程和进程为可以继承
    
    	STARTUPINFO StartInfo = { sizeof(STARTUPINFO) };
    	StartInfo.cb = sizeof(StartInfo);							// STARTUPINFO 结构体用于新进程窗口设置
    	StartInfo.dwFlags = STARTF_USEPOSITION;
    	StartInfo.dwX = 400; StartInfo.dwY = 400;					// 防止窗口重叠
    	PROCESS_INFORMATION ProcessInfo = { 0 };					// 返回进程信息的结构体
    
    	// 创建进程打开 cmd.exe 执行模块
    	TCHAR CmdLine[] = L"cmd.exe";
    	BOOL res = CreateProcess(NULL, CmdLine, &ProcessSec, &ThreadSec, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &StartInfo, &ProcessInfo); // CREATE_NEW_CONSOLE 用于创建一个新的控制台窗口
    	cout << "创建的新进程 ID: " << ProcessInfo.dwProcessId << endl;		// ProcessInfo 结构体包含子进程和线程的 ID
    	cout << "创建的新线程 ID: " << ProcessInfo.dwThreadId << endl;
    
    	WaitForSingleObject(ProcessInfo.hThread, INFINITE);		// 等待线程执行完毕
    	CloseHandle(ProcessInfo.hThread);						// ProcessInfo 结构体包含子进程和线程的句柄
    	WaitForSingleObject(ProcessInfo.hProcess, INFINITE);	// 等待进程执行完毕
    	GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode);	// 获取进程退出代码
    	cout << ExitCode << endl;
    	CloseHandle(ProcessInfo.hProcess);						// 关闭进程句柄
    
    	return 0;
    }
    
    • 手动提升程序权限
    #include <Windows.h>
    #include <iostream>
    #include <strsafe.h>
    using namespace std;
    
    void ErrorExit(LPTSTR lpszFunction, DWORD LastError);
    int main(int argc, char *argv[], TCHAR *env[])
    {
    	SHELLEXECUTEINFOW ExeInfo = { sizeof(ExeInfo) }; // 初始化结构体
    	ExeInfo.lpVerb = TEXT("runas"); ExeInfo.lpFile = TEXT("cmd.exe"); ExeInfo.nShow = SW_SHOWNORMAL; // 设置操作的文件
    	if (!ShellExecuteEx(&ExeInfo))
    	{
    		DWORD LastError = GetLastError(); 		  // 获取权限失败,保存错误代码
    		TCHAR ErrString[10] = L"错误代码";
    		ErrorExit(ErrString, LastError);		  // 调用 ErrorExit 函数打印详细信息
    	}	
    	else
    	{
    		cout << "调用成功" << endl;
    	}
    	return 0;
    }
    
    void ErrorExit(LPTSTR lpszFunction, DWORD LastError)
    {
    	// 检索最后错误码的系统错误消息
    
    	LPVOID lpMsgBuf;
    	LPVOID lpDisplayBuf;
    	DWORD dw = LastError;                      // 模拟错误代码定义为 123
    
    	FormatMessage(
    		FORMAT_MESSAGE_ALLOCATE_BUFFER | // 函数自动使用 LocalAlloc 函数,来为 lpBuffer 分配内存
    		FORMAT_MESSAGE_FROM_SYSTEM |	 // 定义可以使用 GetLastError 的返回值赋给 dw 
    		FORMAT_MESSAGE_IGNORE_INSERTS,   // 这个标志表示 Arguments 参数将被忽略
    		NULL,							 // 消息所在位置,这个参数类型,根据dwFlags标志来设定
    		dw,								 // 消息索引,如果 lpSource 是一个字符串,那么这个参数被忽略
    		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),  // 设置为本地默认语言
    		(LPTSTR)&lpMsgBuf,				 // 接受消息字符串的内存块
    		0,								 // 内存大小
    		NULL);							 // 消息中的参数		
    
    	// 显示错误消息并退出进程
    
    	lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, // 将内存初始化为 0
    		(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); // 为字符串指针区域申请足够大小的内存
    
    	StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf),  // 目标缓冲区和目标缓冲区的大小
    		TEXT("%s %d 的含义是: %s"),			 // 格式字符串
    		lpszFunction,						 // 参数1
    		dw,									 // 参数2
    		lpMsgBuf);							 // 参数3
    
    	MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
    
    	LocalFree(lpMsgBuf);      // 释放空间
    	LocalFree(lpDisplayBuf);
    	ExitProcess(dw);		  // 关闭进程
    }
    
    
    • 查看是否为上下文管理员权限
    #include <Windows.h>
    #include <iostream>
    #include <shlobj.h>
    #include <strsafe.h>
    using namespace std;
    
    VOID WINAPI ErrorCodeTransformation(DWORD ErrorCode);
    DWORD WINAPI GetProcessElevation(TOKEN_ELEVATION_TYPE *pElevationType, BOOL* lsAdmin);
    
    int main(INT argc, CHAR *argv[], TCHAR *env[])
    {
    	// pElevationType 为令牌的上下文权限类型,IsAdmin 标识是否为管理员权限
    	TOKEN_ELEVATION_TYPE pElevationType; BOOL IsAdmin;
    	if (GetProcessElevation(&pElevationType, &IsAdmin))
    	{
    		switch (pElevationType)
    		{
    		case TokenElevationTypeDefault:
    			cout << "[-] 进程以默认用户运行,或者UAC被禁用" << endl; break;
    		case TokenElevationTypeFull:
    			cout << "[*] 进程的权限被成功提升,而且令牌没有被筛选过" << endl; break;
    		case TokenElevationTypeLimited:
    			cout << "[*] 进程使用和一个筛选过的令牌对应的受限的权限运行" << endl; break;
    		}
    		if (IsAdmin) cout << "[*] 进程为管理员权限" << endl;
    		else cout << "[-] 进程为普通权限" << endl;
    	}
    	else
    	{
    		DWORD ErrorCode = GetProcessElevation(&pElevationType, &IsAdmin);
    		ErrorCodeTransformation(ErrorCode);// 打印错误信息
    	}
    	return 0;
    }
    
    DWORD WINAPI GetProcessElevation(TOKEN_ELEVATION_TYPE *pElevationType, BOOL* pIsAdmin)
    {
    	HANDLE hToken = NULL; DWORD dwSize; DWORD ErrorCode = NULL;
    	// OpenProcessToken 用于打开当前进程的令牌,hToken 为令牌的句柄
    	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
    	{
    		// 调用失败返回错误代码
    		ErrorCode = GetLastError();
    		return (ErrorCode);
    	}
    
    	BOOL bResult = FALSE;
    	// GetTokenInformation 用于获取当前令牌是什么令牌,令牌种类储存在 pElevationType 中
    	if (GetTokenInformation(hToken, TokenElevationType, pElevationType, sizeof(TOKEN_ELEVATION_TYPE), &dwSize))
    	{
    		BYTE adminSID[SECURITY_MAX_SID_SIZE];
    		dwSize = sizeof(adminSID);
    		// CreateWellKnownSid 定义一个描述符为 WinBuiltinAccessControlAssistanceOperatorsSid 的别名 SID
    		// adminSID 中储存的是新的 SID
    		CreateWellKnownSid(WinBuiltinAccessControlAssistanceOperatorsSid, NULL, &adminSID, &dwSize);
    		// 如果当前进程的令牌被筛选过
    		if (*pElevationType == TokenElevationTypeLimited)
    		{
    			HANDLE hUnfilteredToken = NULL;
    			// 获取当前进程未筛选过令牌的句柄,句柄保存在 hUnfilteredToken
    			GetTokenInformation(hToken, TokenLinkedToken, (VOID *)&hUnfilteredToken, sizeof(HANDLE), &dwSize);
    			// CheckTokenMembership 用于将模拟令牌和创建的安全描述符做比较,判断令牌的上下文访问权限是否为管理员
    			if (CheckTokenMembership(hUnfilteredToken, &adminSID, pIsAdmin)) bResult = TRUE;
    			CloseHandle(hUnfilteredToken);
    		}
    		else
    		{	// IsUserAnAdmin 函数是 CheckTokenMembership 的包装函数
    			// 建议直接调用该函数以确定管理员组状态,而不是调用 IsUserAnAdmin
    			*pIsAdmin = IsUserAnAdmin();
    			bResult = TRUE;
    		}
    	}
    	CloseHandle(hToken);
    	return (bResult);
    }
    
    // 如果返回错误,可调用此函数打印详细错误信息
    VOID WINAPI ErrorCodeTransformation(DWORD ErrorCode)
    {
    	LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = ErrorCode;
    	// 将错误代码转换为错误信息
    	FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
    		NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL
    	);
    	lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
    	// 格式化打印
    	StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf), TEXT("错误代码 %d :  %s"), dw, lpMsgBuf);
    	// 输出错误信息
    	MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
    	// 释放资源
    	LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw);		  
    }
    
    • 获取系统进程列表,操作进程句柄
    #include <Windows.h>
    #include <iostream>
    #include <shlobj.h>
    #include <strsafe.h>
    #include <stdio.h>
    #include <tlhelp32.h>
    using namespace std;
    
    VOID WINAPI ErrorCodeTransformation(DWORD ErrorCode);
    DWORD WINAPI ProcessInfo(VOID);
    DWORD WINAPI ProcessHandle(DWORD ProcessID);
    
    int main(INT argc, CHAR *argv[], TCHAR *env[])
    {
    	DWORD ErrorCode = ProcessInfo();
    	// 打印详细的错误信息
    	ErrorCodeTransformation(ErrorCode); 
    	return 0;
    }
    
    DWORD WINAPI ProcessInfo(VOID)
    {
    	// ErrorCode 用于统计错误信息,ProcessCount 用于统计进程数
    	DWORD ErrorCode = NULL; INT ProcessCount = 0;
    	// 使用 CreateToolhelp32Snapshot 获取当前所有的进程快照
    	HANDLE ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_INHERIT | TH32CS_SNAPALL, 0);
    	if (ProcessSnapshot == INVALID_HANDLE_VALUE)
    	{
    		// 调用错误返回错误代码,以便查出详细的错误信息
    		ErrorCode = GetLastError();
    		return (ErrorCode);
    	}
    	PROCESSENTRY32W ProcessInfo; ProcessInfo.dwSize = sizeof(ProcessInfo); // 必须初始化结构体大小
    	// Process32First 用于获取第一个进程,返回进程信息至 ProcessInfo 结构体
    	BOOL DisResult = Process32First(ProcessSnapshot, &ProcessInfo); 
    	if (!DisResult)
    	{
    		// 调用错误返回错误代码,以便查出详细的错误信息
    		ErrorCode = GetLastError();
    		return (ErrorCode);
    	}
    	// 进程数量加一
    	ProcessCount++;
    	cout << "  显示进程 ID:  " << ProcessInfo.th32ProcessID << endl;
    	while (DisResult)
    	{
    		ProcessCount++;
    		// 获取下一个进程的详细信息
    		DisResult = Process32Next(ProcessSnapshot, &ProcessInfo);
    		// 打印进程 ID
    		cout << "  ID:  " << ProcessInfo.th32ProcessID;
    		// 有关句柄的详细操作
    		ProcessHandle(ProcessInfo.th32ProcessID);
    		// 打印进程名称
    		printf("  进程名: %ls
      ", ProcessInfo.szExeFile);
    	}
    	return 0;
    }
    
    DWORD WINAPI ProcessHandle(DWORD ProcessID)
    {
    	DWORD ErrorCode = NULL;
    	// OpenProcess 将进程 ID 转换进程句柄,方便对进程进行操作
    	HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, TRUE, ProcessID);
    	if (!ProcessHandle)
    	{
    		// 调用错误返回错误代码,以便查出详细的错误信息
    		ErrorCode = GetLastError();
    		if (ErrorCode == 5) cout << "  访问状态: 拒绝访问  ";
    		return (ErrorCode);
    	}
    	else
    	{
    		// 操作进程句柄....
    	
    	}
    	// 关闭句柄
    	CloseHandle(ProcessHandle);
    	return TRUE;
    }
    
    // 如果返回错误,可调用此函数打印详细错误信息
    VOID WINAPI ErrorCodeTransformation(DWORD ErrorCode)
    {
    	LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = ErrorCode;
    	// 将错误代码转换为错误信息
    	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
    		NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL
    	);
    	lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
    	StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf), TEXT("错误代码 %d :  %s"), dw, lpMsgBuf);
    	// 弹窗显示错误信息
    	MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
    	LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw);
    }
    

    在这里插入图片描述

  • 相关阅读:
    MySQL数据库初识
    Python中面向对象初识到进阶
    python 函数进阶
    Python 函数的初识
    Python的发展与应用
    什么是产品经理 以及职责
    I/O----复制文本文件
    获取次日日期(主要两种方法)
    vector以及array和数组
    编辑软件注释快捷键
  • 原文地址:https://www.cnblogs.com/csnd/p/11800524.html
Copyright © 2020-2023  润新知