您的位置:首页 > 其它

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

2010-05-20 10:22 771 查看
进程提供了程序运行所需要的资源,虚拟内存地址空间......
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();  
  }  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐