创建进程
分别创建MFC应用程序和Win32应用程序
MFC应用程序界面设置
win32子进程内容
#include <Windows.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdshow)
{
MessageBox(NULL, lpCmdLine, L"提示", MB_OK);
return 0;
}
将*.exe放入到主线程的Debug中
创建进程传递参数
void CParentDlg::OnBnClickedBtnStart()
{
for (int i = 0; i < 10; i++)
{
//创建子进程
//第二个参数不能传递常量,而应该传递一块内存
/*启动顺序:
1.父进程所在目录
2.Windows系统目录
TCHAR szPath[MAX_PATH];
GetSystemDirectory(szPath,MAX_PATH);//获取系统目录
3.Windows目录
4.环境变量指定目录
*/
wchar_t szExePath[MAX_PATH] = L"sub.exe";
wsprintf(szExePath, L"sub.exe %d-%d", i*100, i*100 + 99);
//第三个参数:进程安全属性填写为NULL,表示为默认安全属性
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;//表示默认
sa.bInheritHandle = TRUE;
//第四个参数:线程安全属性
//第五个参数:指示新进程是否从调用进程继承句柄
//第六个参数:创建标记 0代表默认
//第七个参数:环境变量
//第八个参数:工作目录
//第九个参数:启动信息
STARTUPINFO si = { sizeof(STARTUPINFO) };
//si.cb = sizeof(STARTUPINFO);
//第十个参数进程信息
PROCESS_INFORMATION pi = { 0 };
if (TRUE == CreateProcess(NULL, szExePath, &sa, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
m_hSub[i] = pi.hProcess;//获取进程句柄
}
}
}
关闭进程
void CParentDlg::OnBnClickedBtnStop()
{
for (int i = 0; i < 10; i++)
{
if (m_hSub[i] != NULL)
{
//等待信号改变
//WaitForSingleObject(m_hSub[i], INFINITE);
//引用计数
CloseHandle(m_hSub[i]);//减小引用技术
MessageBox(L"程序已关闭", L"提示",MB_OK);
//强制关闭一个进程
TerminateProcess(m_hSub[i], 0);//关闭代码,退出
}
}
}
通过配置文件读取
配置文件
获取配置文件
bool CParentDlg::InitEnvironment()
{
//读取配置文件
//address of section name
//address of key name
//return value if key name is not found
//address of initialization filename
m_subProcessNum=GetPrivateProfileInt(L"Base",L"subProcessNum",0,L"D:\\MFCProject\\Parent\\Debug\\Parent.ini");
if (m_subProcessNum != 0)
{
m_hSub = new HANDLE[m_subProcessNum];
}
return TRUE;
}
点击按钮
void CParentDlg::OnBnClickedBtnStart()
{
InitEnvironment();//初始化环境
for (int i = 0; i < CParentDlg::m_subProcessNum; i++)
{
//创建子进程
//第二个参数不能传递常量,而应该传递一块内存
/*启动顺序:
1.父进程所在目录
2.Windows系统目录
TCHAR szPath[MAX_PATH];
GetSystemDirectory(szPath,MAX_PATH);//获取系统目录
3.Windows目录
4.环境变量指定目录
*/
wchar_t szExePath[MAX_PATH] = L"sub.exe";
wsprintf(szExePath, L"sub.exe %d-%d", i*100, i*100 + 99);
//第三个参数:进程安全属性填写为NULL,表示为默认安全属性
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;//表示默认
sa.bInheritHandle = TRUE;
//第四个参数:线程安全属性
//第五个参数:指示新进程是否从调用进程继承句柄
//第六个参数:创建标记 0代表默认
//第七个参数:环境变量
//第八个参数:工作目录
//第九个参数:启动信息
STARTUPINFO si = { sizeof(STARTUPINFO) };
//si.cb = sizeof(STARTUPINFO);
//第十个参数进程信息
PROCESS_INFORMATION pi = { 0 };
if (TRUE == CreateProcess(NULL, szExePath, &sa, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
m_hSub[i] = pi.hProcess;//获取进程句柄
}
}
//等待信号的变化
//WaitForMultipleObjects(m_subProcessNum, CParentDlg::m_hSub,TRUE, INFINITE);
}
全部代码
// ParentDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "Parent.h"
#include "ParentDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CParentDlg 对话框
CParentDlg::CParentDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_PARENT_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_subProcessNum = 0;
m_hSub = NULL;
}
CParentDlg::~CParentDlg()
{
if (m_hSub != NULL)
{
delete[] m_hSub;
m_hSub = NULL;
}
}
void CParentDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CParentDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_START, &CParentDlg::OnBnClickedBtnStart)
ON_BN_CLICKED(IDC_BTN_STOP, &CParentDlg::OnBnClickedBtnStop)
END_MESSAGE_MAP()
// CParentDlg 消息处理程序
BOOL CParentDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CParentDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CParentDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CParentDlg::OnBnClickedBtnStart()
{
InitEnvironment();//初始化环境
for (int i = 0; i < CParentDlg::m_subProcessNum; i++)
{
//创建子进程
//第二个参数不能传递常量,而应该传递一块内存
/*启动顺序:
1.父进程所在目录
2.Windows系统目录
TCHAR szPath[MAX_PATH];
GetSystemDirectory(szPath,MAX_PATH);//获取系统目录
3.Windows目录
4.环境变量指定目录
*/
wchar_t szExePath[MAX_PATH] = L"sub.exe";
wsprintf(szExePath, L"sub.exe %d-%d", i*100, i*100 + 99);
//第三个参数:进程安全属性填写为NULL,表示为默认安全属性
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;//表示默认
sa.bInheritHandle = TRUE;
//第四个参数:线程安全属性
//第五个参数:指示新进程是否从调用进程继承句柄
//第六个参数:创建标记 0代表默认
//第七个参数:环境变量
//第八个参数:工作目录
//第九个参数:启动信息
STARTUPINFO si = { sizeof(STARTUPINFO) };
//si.cb = sizeof(STARTUPINFO);
//第十个参数进程信息
PROCESS_INFORMATION pi = { 0 };
if (TRUE == CreateProcess(NULL, szExePath, &sa, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
m_hSub[i] = pi.hProcess;//获取进程句柄
}
}
//等待信号的变化
//WaitForMultipleObjects(m_subProcessNum, CParentDlg::m_hSub,TRUE, INFINITE);
}
void CParentDlg::OnBnClickedBtnStop()
{
for (int i = 0; i < 10; i++)
{
if (m_hSub[i] != NULL)
{
//等待信号改变
//WaitForSingleObject(m_hSub[i], INFINITE);
//引用计数
CloseHandle(m_hSub[i]);//减小引用技术
MessageBox(L"程序已关闭", L"提示",MB_OK);
//强制关闭一个进程
TerminateProcess(m_hSub[i], 0);//关闭代码,退出
}
}
}
bool CParentDlg::InitEnvironment()
{
//读取配置文件
//address of section name
//address of key name
//return value if key name is not found
//address of initialization filename
m_subProcessNum=GetPrivateProfileInt(L"Base",L"subProcessNum",0,L"D:\\MFCProject\\Parent\\Debug\\Parent.ini");
if (m_subProcessNum != 0)
{
m_hSub = new HANDLE[m_subProcessNum];
}
return TRUE;
}
// ParentDlg.h: 头文件
//
#pragma once
// CParentDlg 对话框
class CParentDlg : public CDialogEx
{
// 构造
public:
CParentDlg(CWnd* pParent = nullptr); // 标准构造函数
~CParentDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_PARENT_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
HANDLE* m_hSub;
afx_msg void OnBnClickedBtnStart();
afx_msg void OnBnClickedBtnStop();
bool InitEnvironment();
int m_subProcessNum;
};
打开进程
ui界面
设置关联变量
获取窗口句柄
关闭按钮
void COpenDlg::OnBnClickedBtnClose()
{
UpdateData(TRUE);//刷新 TRUE 代表把界面上显示的数值,更新到关联变量中
//获得一个窗口名和类型名
HWND hWnd = ::FindWindow(m_strWindowClass,m_strWindowTitle);
if (hWnd == NULL)
{
MessageBox(L"没有找到");
return;
}
//通过窗口句柄获得进程ID
DWORD dwPID;
GetWindowThreadProcessId(hWnd, &dwPID);
//打开进程
//第一个参数:访问权限
//第二个参数:
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE, dwPID);
if (hProcess == NULL)
{
MessageBox(L"打开进程失败");
return;
}
//关闭进程
TerminateProcess(hProcess,0);
}
便利进程
初始化列表
BOOL CergodicProcessDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
m_list.InsertColumn(0, _T("进程名"), LVCFMT_LEFT, 120);
m_list.InsertColumn(1, _T("PID"), LVCFMT_LEFT, 100);
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);//扩展样式,显示高亮
m_list2.InsertColumn(0, _T("模块路径"), LVCFMT_LEFT, 200);
m_list2.SetExtendedStyle(LVS_EX_FULLROWSELECT);//扩展样式
EnumProcess();
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
创建进程快照
void CergodicProcessDlg::EnumProcess()
{
//创建进程快照
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
//返回进程列表
PROCESSENTRY32 pe32{sizeof(PROCESSENTRY32)};//枚举驻留的进程
BOOL b=Process32First(hSnapshot, &pe32);
int i = 0;
while (b)
{
m_list.InsertItem(i, pe32.szExeFile);
CString str;
str.Format(L"%d", pe32.th32ParentProcessID);
m_list.SetItemText(i, 1, str);
b=Process32Next(hSnapshot, &pe32);//获取下一个进程
i++;
}
}
创建进程模块
void CergodicProcessDlg::EnumModule(DWORD dwPID)
{
//创建进程快照
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
//返回进程列表
MODULEENTRY32 me32{ sizeof(MODULEENTRY32) };//枚举驻留的进程
BOOL b = Module32First(hSnapshot, &me32);
int i = 0;
while (b)
{
m_list2.InsertItem(i, me32.szExePath);
b = Module32Next(hSnapshot, &me32);//获取下一个进程
i++;
}
}
点击进程获取进程模块文章来源:https://www.toymoban.com/news/detail-528520.html
文章来源地址https://www.toymoban.com/news/detail-528520.html
void CergodicProcessDlg::OnDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
int nSel = m_list.GetSelectionMark();//获取选中的
if (nSel < 0)
return;
DWORD dwPID = _wtoi(m_list.GetItemText(nSel, 1));
m_list2.DeleteAllItems();//删除原来的
EnumModule(dwPID);
*pResult = 0;
}
到了这里,关于14 MFC多进程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!