#在实验中遇到代码版本适配问题#
在实验中,指导书给出的代码仅仅适配VC++06,而目前大多数使用的是VS2022则会导致适配问题出现代码不可使用或异常报错,以下是本人结合AI进行的改正后可以正常适配VS2022的版本
一、实验:
Windows进程管理
1-1
# include <iostream>
void main()
{
std::cout << "Hello, Win32 Consol Application" << std::endl;
}
这个代码实现的功能简单不存在适配问题
1-2
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <iostream>
#include <tchar.h>
// 创建传递过来的进程的克隆过程并赋于其ID值
void StartClone(int nCloneID)
{
// 提取用于当前可执行文件的文件名
TCHAR szFilename[MAX_PATH];
GetModuleFileName(NULL, szFilename, MAX_PATH);
// 格式化用于子进程的命令行并通知其EXE文件名和克隆ID
TCHAR szCmdLine[MAX_PATH];
_sntprintf_s(szCmdLine, MAX_PATH, _T("\"%s\" %d"), szFilename, nCloneID);
// 用于子进程的STARTUPINFO结构
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si); // 必须是本结构的大小
// 返回的用于子进程的进程信息
PROCESS_INFORMATION pi;
// 利用同样的可执行文件和命令行创建进程,并赋于其子进程的性质
BOOL bCreateOK = ::CreateProcess(
szFilename, // 产生这个EXE的应用程序的名称
szCmdLine, // 告诉其行为像一个子进程的标志
NULL, // 缺省的进程安全性
NULL, // 缺省的线程安全性
FALSE, // 不继承句柄
CREATE_NEW_CONSOLE, // 使用新的控制台
NULL, // 新的环境
NULL, // 当前目录
&si, // 启动信息
&pi); // 返回的进程信息
// 对子进程释放引用
if (bCreateOK)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
int _tmain(int argc, TCHAR* argv[])
{
// 确定派生出几个进程,及派生进程在进程列表中的位置
int nClone = 0;
if (argc > 1)
{
// 从第二个参数中提取克隆ID
_stscanf_s(argv[1], _T("%d"), &nClone);
}
// 显示进程位置
_tprintf(_T("Process ID: %d, Clone ID: %d\n"), GetCurrentProcessId(), nClone);
const int c_nCloneMax = 5;
if (nClone < c_nCloneMax)
{
// 发送新进程的命令行和克隆号
StartClone(++nClone);
}
// 等待响应键盘输入结束进程
getchar();
return 0;
}
此段代码改动如下:
1、在首部增加宏定义解决 _CRT_SECURE_NO_WARNINGS报错问题
2、第15、58行解决字符匹配问题使用安全的字符串处理函数
1-3
#include <windows.h>
#include <iostream>
#include <tchar.h> // 包含了 TCHAR 相关的宏和函数
static LPCTSTR g_szMutexName = _T("w2kdg.ProcTerm.mutex.Suicide");
void StartClone()
{
TCHAR szFilename[MAX_PATH];
GetModuleFileName(NULL, szFilename, MAX_PATH);
TCHAR szCmdLine[MAX_PATH];
_stprintf_s(szCmdLine, MAX_PATH, _T("\"%s\" child"), szFilename); // 使用 _stprintf_s 来格式化字符串
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
BOOL bCreateOK = CreateProcess(
szFilename,
szCmdLine,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
if (bCreateOK)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else
{
std::cerr << "Failed to create child process. Error: " << GetLastError() << std::endl;
}
}
void Parent()
{
HANDLE hMutexSuicide = CreateMutex(
NULL,
TRUE,
g_szMutexName);
if (hMutexSuicide != NULL)
{
std::cout << "Creating the child process." << std::endl;
StartClone();
std::cout << "Telling the child process to quit." << std::endl;
getchar(); // 等待用户输入以保证子进程已经开始执行
ReleaseMutex(hMutexSuicide);
CloseHandle(hMutexSuicide);
}
else
{
std::cerr << "Failed to create mutex. Error: " << GetLastError() << std::endl;
}
}
void Child()
{
HANDLE hMutexSuicide = OpenMutex(
SYNCHRONIZE,
FALSE,
g_szMutexName);
if (hMutexSuicide != NULL)
{
std::cout << "Child waiting for suicide instructions." << std::endl;
DWORD dwWaitResult = WaitForSingleObject(hMutexSuicide, INFINITE);
if (dwWaitResult == WAIT_OBJECT_0)
{
std::cout << "Child received quit instruction." << std::endl;
CloseHandle(hMutexSuicide);
}
else if (dwWaitResult == WAIT_TIMEOUT)
{
std::cout << "Child still waiting for instructions." << std::endl;
// 可以继续执行其他操作或等待
}
else
{
std::cerr << "WaitForSingleObject failed with error: " << GetLastError() << std::endl;
}
}
else
{
std::cerr << "Failed to open mutex. Error: " << GetLastError() << std::endl;
}
}
int _tmain(int argc, TCHAR* argv[])
{
if (argc > 1 && _tcscmp(argv[1], _T("child")) == 0)
{
Child();
}
else
{
Parent();
}
return 0;
}
第三段代码改动较多,加入启动失败判断并且使用了安全的字符串函数。
以上,为全部修改后的代码,为方便实验而修改。如有问题欢迎指正。