在一个进程中启动另一个进程---CreateProcess API

进程提供了程序运行所需要的资源,虚拟内存地址空间......
exe文件加载到进程的虚拟地址空间内存中指定的位置.

每个进程都有一个标识符(PID)和一个句柄,系统和其他进程可以通过PID和进程的句柄对进程进行管理操作

动态库的原理
如:API函数CreateFile可执行代码在Kernel32.dll中,"内存分页管理"将多个虚拟内存分页映射到同一个物理分页上.

动态链接过程,exe文件中的导入表,初始化时将动态库加载到内存的虚拟地址空间中.
"动态链接"和"静态链接".

线程,纤程与作业
1.线程(Thread)
2.纤程(Fiber)
3.作业(Job,也称为工作项)
作业是一种对象,可以将一组进程作为一个单元进行管理.
包括:命名对象(namable),安全对象(securable)和共享对象(sharable)

创建进程,获取进程相关信息,获取启动函数
1.父进程和子进程
2.启动参数
GetCommandLine,GetStartupInfo函数获得启动参数,启动信息.
3.进程句柄和进程标识
如果想知道自己的句柄,可以使用
GetCurrentProcess和GetCurrentProcessId函数获取自己的句柄和PID.
可以使用GetPriorityClass,GetProcessTimes,GetProcessVersion,GetProcessWorkingSetSize函数获取进程的相关消息
获得其他进程PID,可以通过OpenProcess函数获得进程句柄,也可通过GetProcessId通过句柄获得PID.

退出和终止程序
ExitProcess或TerminateProcess.

关键API
CreateProcess
另外还有CreateProcessAsUser,CreateProcessWithLogonW,CreateProcessWithTokenW.
WinExec函数功能也是执行程序.

BOOL WINAPI CreateProcess(
__in          LPCTSTR lpApplicationName, //指向启动exe文件
__in_out      LPTSTR lpCommandLine, //启动进程命令行
__in          LPSECURITY_ATTRIBUTES lpProcessAttributes, //SECURITY_ATTRIBUTES结构变量,为进程设置安全属性
__in          LPSECURITY_ATTRIBUTES lpThreadAttributes, //进程句柄是否可以被子进程继承
__in          BOOL bInheritHandles, //与子进程句柄基础关系
__in          DWORD dwCreationFlags, //进程创建标志和优先级控制
__in          LPVOID lpEnvironment, //指向新进程环境变量块,null指使用父进程环境变量块
__in          LPCTSTR lpCurrentDirectory, //指定创建后新进程的当前目录,null为父进行的当前目录
__in          LPSTARTUPINFO lpStartupInfo, //设定启动信息,A pointer to a STARTUPINFO or STARTUPINFOEX 两结构.
__out         LPPROCESS_INFORMATION lpProcessInformation //A pointer to a PROCESS_INFORMATION structure that receives identification information about the new process
);                                                          //返回进程信息

创建进程实例:
/* 头文件 */
#include <windows.h>
#include <stdio.h>

DWORD CreateChildProcess(LPSTR szChildProcessCmd);

/*************************************
* int main(void)
* 功能 演示进程创建
*
* 参数 未使用
**************************************/
int main()
{
CreateChildProcess("Child.exe abc 123");
}
/*************************************
* DWORD CreateChildProcess(LPSTR szChildProcessCmd)
* 功能 演示创建子进程
*
* 参数 LPSTR szChildProcessCmd 启动子进程的命令行
* 返回值 成功返回,失败返回
**************************************/
DWORD CreateChildProcess(LPSTR szChildProcessCmd)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
// 将启动信息结构清零
ZeroMemory( &si, sizeof(si) );
// 设置结构大小,cb属性应为结构的大小
si.cb = sizeof(si);
// 将进程信息结构清零
ZeroMemory( &pi, sizeof(pi) );

// 创建子进程,并判断是否成功
if( !CreateProcess( NULL,   // 使用命令行
   szChildProcessCmd,    // 命令行
   NULL,             // 不继承进程句柄
   NULL,             // 不继承线程句柄
   FALSE,            // 不继承句柄
   0,                // 没有创建标志
   NULL,             // 使用父进程环境变量
   NULL,             // 使用父进程目录作为当前目录
   &si,              // STARTUPINFO 结构
   &pi )             // PROCESS_INFORMATION 保存相关信息
   )
{
   // 创建失败
   printf( "CreateProcess failed (%d)./n", GetLastError() );
   return 1;
}
// 在创建成功后父进程也可直接退出,这里等待子进程执行结束

// 等待子进程结束
// 使用到了通过PROCESS_INFORMATION 返回的相关信息,hProcess为子进程句柄
// 父进程也可以不等待子进程运行完成而直接退出
WaitForSingleObject( pi.hProcess, INFINITE );
// 关闭进程句柄和线程句柄
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return 0;
}

子进程:
/* 头文件 */
#include <windows.h>
#include <stdio.h>
/* 宏定义 */
#define MyAlloc(size) HeapAlloc(GetProcessHeap(),0,size)
#define MyFree(lpMem) HeapFree(GetProcessHeap(),0,lpMem)
/* 结构体定义 */
typedef struct _PROCESS_INFO
{
DWORD dwPid;
HANDLE hProcess;
DWORD dwPrioClass;
DWORD dwHandleCount;
DWORD dwAffinityMask;
SIZE_T dwWorkingSetSizeMax;
SIZE_T dwWorkingSetSizeMin;
LPWSTR szwCommandLine;
STARTUPINFO sti;
}PROCESS_INFO, *LPPROCESS_INFO;
/* 全局变量 */
HANDLE hMySelf;
/* 函数声明 */
DWORD GetProcessInfo(LPPROCESS_INFO lppi);

/*************************************
* int WinMain(
HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
* 功能 演示获取进程信息,在进程中获取命令行参数等
*
**************************************/
int WinMain(
HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
)
{
PROCESS_INFO pi;
INT argc;
WCHAR **argv;
DWORD i;
DWORD dwBufferSize = lstrlen(lpCmdLine)+MAX_PATH+1024;
LPSTR szShowBuffer = (LPSTR)MyAlloc(dwBufferSize);

hMySelf = hInstance;
// 显示直接从WinMain函数参数得到的信息
wsprintf(szShowBuffer,
   "启动参数/n实例句柄:%.8X,命令行参数:%s,显示选项:%.8X",
   hInstance,lpCmdLine,nCmdShow);
MessageBox(NULL,szShowBuffer,"WinMain函数参数",MB_OK);
// 使用自定义的函数获取相关信息
GetProcessInfo(&pi);
// 将命令行参数分离
argv = CommandLineToArgvW(pi.szwCommandLine,&argc);
// 字符处理,并显示
*szShowBuffer = '/x00';
for(i=0; i<argc; i++)
{
   DWORD dwBufferSize = lstrlenW(*argv)+1;
   LPSTR szMBArgv = MyAlloc(dwBufferSize);
   WideCharToMultiByte(CP_ACP,0,*argv,-1,szMBArgv,dwBufferSize,NULL,NULL);
   argv++;
   lstrcat(szShowBuffer,"/n");
   lstrcat(szShowBuffer,szMBArgv);
   MyFree(szMBArgv);
}
MessageBox(NULL,szShowBuffer,"参数",MB_OK);
MyFree(szShowBuffer);
// 打印其他信息 TODO
return 0;
}
/*************************************
* DWORD GetProcessInfo(LPPROCESS_INFO lppi)
* 功能 获取进程相关信息,保存在PROCESS_INFO结构中
*
* 参数 LPPROCESS_INFO lppi 用于保存相关信息
**************************************/
DWORD GetProcessInfo(LPPROCESS_INFO lppi)
{
// PID
lppi->dwPid = GetCurrentProcessId();
// 句柄
lppi->hProcess = GetCurrentProcess();
// 优先级
lppi->dwPrioClass = GetPriorityClass(hMySelf);
// 句柄记数
//windows xp sp1 sdk 新增的API GetProcessHandleCount
//lppi->dwHandleCount
// = GetProcessHandleCount(lppi->hProcess,&lppi->dwHandleCount);

// AffinityMask
GetProcessAffinityMask(hMySelf,
   &lppi->dwAffinityMask,
   NULL);
// WorkingSetSize
GetProcessWorkingSetSize(hMySelf,
   &lppi->dwWorkingSetSizeMin,
   &lppi->dwWorkingSetSizeMax);
lppi->szwCommandLine = GetCommandLineW();
// 启动信息
GetStartupInfo(&lppi->sti);
return 0;
}

 

 

 

 

我们平时常用的:

启动:  
  STARTUPINFO   Si;  
  PROCESS_INFORMATION   Pi;  
   
  memset(&Si,   0,   sizeof(STARTUPINFO));  
  Si.cb   =   sizeof(STARTUPINFO);  
  Si.dwFlags   =   STARTF_USESHOWWINDOW;  
  Si.wShowWindow   =   SW_SHOWNORMAL;  
   
  CreateProcess("c://windows//notepad.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&Si,&Pi))  
   
  关闭:  
  重载OnClose  
   
  void   CXXXXDlg::OnClose()    
  {  
  TerminateProcess(Pi.hProcess,   0);  
  CDialog::OnClose();  
  }  

在Windows API,你可以通过`CreateThread`, `WaitForSingleObject`, 和 `TerminateProcess`等函数来实现这个操作。以下是步骤概述: 1. 首先,你需要找到你要挂起并随后重启的进程ID。这通常需要使用`OpenProcess`函数打开进程,并从返回的`HANDLE`获取进程ID。 ```cpp DWORD processId = GetWindowThreadProcessId(hwnd, &processId); // hwnd是你想要操作的窗口句柄 ``` 2. 然后,使用`CreateThread`创建一个新的线程来挂起进程。这里可以使用`SuspendThread`函数来暂停进程执行。 ```cpp HANDLE hThread = OpenThread(SYNCHRONIZE | THREAD_SUSPEND_RESUME, FALSE, processId); if (hThread != NULL) { SuspendThread(hThread); } else { // 处理无法打开线程的情况 } ``` 3. 接下来,你需要等待一秒钟。你可以创建一个计时器线程,或者使用`Sleep`函数休眠指定时间。注意在实际应用,你可能需要处理超时或断情况。 ```cpp Sleep(1000); // 1秒睡眠 ``` 4. 一分钟后,你可以使用`ResumeThread`来恢复进程的执行。 ```cpp ResumeThread(hThread); CloseHandle(hThread); ``` 5. 最后,如果你想重启该进程,你需要使用`TerminateProcess`结束它,然后再次启动。注意终止进程会关闭所有它的子进程,所以这是一个非正常的过程。 ```cpp TerminateProcess(processId, 0); // 结束进程 // 之后如果需要,你可以考虑使用CreateProcess函数重新创建进程 ``` 请确保在实际操作,你有合法的理由和权限来进行这样的进程管理,同时遵守相关的安全性和法律法规。此外,上述代码只是一个基础示例,可能需要结合异常处理和其他错误检查来编写健壮的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值