CreateProcess的用法

使用编译器vs2008。

 

第一、第二个参数的用法:

 

例子:

使用ie打开指定的网页。

注意第二个参数是 可执行文件+命令行参数

 

 

也可如此:

第一个参数是 可执行文件;第二个参数是 命令行参数

 

 

<think> 我们正在详细讨论Windows API中的CreateProcess函数。根据用户的问题和之前的引用,我们需要提供CreateProcess函数的详细用法。 首先,回顾引用内容: 引用[1]给出了CreateProcess的函数原型和参数说明。 引用[2]提到CreateFunction成功时返回TRUE,并说明了pszApplicationName和pszCommandLine参数的作用。 引用[3]提到了一些限制,主要是关于进程启动时事件的序列化。 引用[4]提到了一个标志CREATE_SEPARATE_WOW_VDM(只适用于Windows NT)的作用。 现在,我们将详细介绍CreateProcess函数: 1. 函数功能:创建一个新进程及其主线程,新进程运行指定的可执行文件。 2. 函数原型(根据引用[1]): BOOL CreateProcess( PCTSTR pszApplicationName, // 可执行文件名称 PTSTR pszCommandLine, // 命令行字符串 PSECURITY_ATTRIBUTES psaProcess, // 进程安全属性 PSECURITY_ATTRIBUTES psaThread, // 线程安全属性 BOOL bInheritHandles, // 是否继承句柄 DWORD fdwCreate, // 创建标志 PVOID pvEnvironment, // 环境块 PCTSTR pszCurDir, // 当前目录 PSTARTUPINFO psiStartInfo, // 启动信息 PPROCESS_INFORMATION ppiProcInfo // 进程信息 ); 3. 参数详解: - pszApplicationName: 指定可执行文件(.exe)的完整路径。可以为NULL,此时可执行文件的名字必须出现在pszCommandLine参数的最前面并用空格分隔。 - pszCommandLine: 指定要传递给新进程的命令行字符串。注意,这是一个可写的字符串缓冲区(因为函数内部可能会修改该字符串,但修改是暂时的)。如果pszApplicationName为NULL,则命令行的第一个部分必须是要执行的文件名(可以包含路径)。 - psaProcess: 指向一个SECURITY_ATTRIBUTES结构,用于指定新进程对象的安全描述符以及是否继承该句柄。通常设为NULL,表示默认安全属性且句柄不可继承。 - psaThread: 同上,但用于新进程的主线程。通常设为NULL。 - bInheritHandles: 指示新进程是否继承调用进程的可继承句柄。TRUE表示继承。 - fdwCreate: 创建标志,多个标志可以用位或(|)组合。常用标志: CREATE_NEW_CONSOLE:新进程使用新的控制台窗口(如果创建的是控制台程序)。 CREATE_SUSPENDED:新进程的主线程被创建为挂起状态,直到调用ResumeThread。 DETACHED_PROCESS:创建一个没有控制台窗口的控制台进程(用于后台服务)。 其他标志可参考MSDN。 - pvEnvironment: 指向新进程的环境块。如果为NULL,则使用父进程的环境。 - pszCurDir: 指定新进程的当前工作目录。如果为NULL,则使用父进程的当前目录。 - psiStartInfo: 指向STARTUPINFO或STARTUPINFOEX结构,用于指定新进程的主窗口特性(如窗口大小、位置、标准句柄等)。在调用CreateProcess前必须初始化该结构(至少设置cb成员为结构大小)。 - ppiProcInfo: 指向PROCESS_INFORMATION结构,用于接收新进程的标识信息(进程ID、线程ID、进程句柄、线程句柄)。调用者必须关闭返回的两个句柄。 4. 返回值:函数成功返回TRUE,失败返回FALSE,可调用GetLastError获取错误代码。 5. 注意事项: - 根据引用[2],命令行字符串(pszCommandLine)参数是一个非常量字符串,尽管CreateProcess内部不会永久修改该字符串,但在函数返回前,可能会临时修改,因此不能传递常量字符串(如字符串字面值)。 - 引用[3]提到,在进程启动时,一系列事件(ExitProcess, ExitThread, CreateThread, CreateRemoteThread)是序列化进行的,因此在一个地址空间中,同一时间只有一个事件发生。这意味着在DLL初始化代码中创建线程是安全的,但要注意避免死锁。 - 引用[4]提到的CREATE_SEPARATE_WOW_VDM标志,仅用于16位Windows应用程序,且只在Windows NT系统中有效。它会覆盖WIN.INI中DefaultSeparateVDM的设置,强制在单独的VDM中运行。 6. 使用步骤: a. 准备STARTUPINFO结构:通常先清零,然后设置cb成员为结构大小。 b. 准备PROCESS_INFORMATION结构:不需要初始化,由CreateProcess填充。 c. 调用CreateProcess,传递参数。 d. 检查返回值,若成功,则使用PROCESS_INFORMATION中的句柄和ID。 e. 关闭PROCESS_INFORMATION中的句柄(进程句柄和线程句柄),避免资源泄漏。 7. 示例代码片段: STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; if (CreateProcess( NULL, // 使用命令行指定可执行文件 "notepad.exe", // 命令行字符串(必须是可修改的缓冲区,这里为了示例使用字面值,实际中应使用数组) NULL, // 进程安全属性 NULL, // 线程安全属性 FALSE, // 不继承句柄 0, // 无标志 NULL, // 使用父进程环境 NULL, // 使用父进程当前目录 &si, // 启动信息 &pi) // 进程信息 ) { // 成功,关闭句柄 CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } 注意:上面的示例中,命令行字符串直接传递字符串字面值,这在某些编译器下可能会引发错误(因为需要可修改的缓冲区)。实际使用时应将命令行字符串存放在可修改的字符数组中。 修正后的示例: TCHAR cmdLine[] = TEXT("notepad.exe"); if (CreateProcess(NULL, cmdLine, ...)) { ... } 8. 补充:如果希望等待新进程结束,可以使用WaitForSingleObject(pi.hProcess, INFINITE)。 9. 错误处理:如果CreateProcess失败,可以调用GetLastError()获取错误代码,然后转换成错误消息。 下面是一个更完整的示例(使用宽字符版本): #include <windows.h> #include <tchar.h> #include <stdio.h> int main() { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); // 准备命令行(可修改的缓冲区) TCHAR cmdLine[] = _T("notepad.exe"); // 创建进程 if (!CreateProcess(NULL, // 应用程序名称(NULL表示从命令行获取) cmdLine, // 命令行 NULL, // 进程安全属性 NULL, // 线程安全属性 FALSE, // 不继承句柄 0, // 无创建标志 NULL, // 使用父进程的环境 NULL, // 使用父进程的当前目录 &si, // 指向STARTUPINFO的指针 &pi) // 指向PROCESS_INFORMATION的指针 ) { _tprintf(_T("CreateProcess failed (%d).\n"), GetLastError()); return 1; } // 等待进程结束 WaitForSingleObject(pi.hProcess, INFINITE); // 关闭句柄 CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; } 10. 常见问题: - 如果pszApplicationName和pszCommandLine都指定了可执行文件,系统优先使用pszApplicationName。 - 为了运行批处理文件(.bat或.cmd)或者其他非可执行文件,应该将pszApplicationName设为NULL,并在pszCommandLine中指定解释器(如cmd.exe /c mybatch.bat)。 - 新进程的创建独立于父进程,因此父进程可以继续执行而不需要等待子进程。 最后,根据要求生成相关问题。 </think> ### CreateProcess函数用法详解 `CreateProcess`是Windows API中用于创建新进程的核心函数,其功能等价于Linux中的`fork/exec`组合。以下是详细用法说明: #### 函数原型 ```cpp BOOL CreateProcess( PCTSTR pszApplicationName, // 可执行文件名 PTSTR pszCommandLine, // 命令行参数 PSECURITY_ATTRIBUTES psaProcess,// 进程安全属性 PSECURITY_ATTRIBUTES psaThread, // 线程安全属性 BOOL bInheritHandles, // 句柄继承标志 DWORD fdwCreate, // 创建标志 PVOID pvEnvironment, // 环境变量 PCTSTR pszCurDir, // 当前目录 PSTARTUPINFO psiStartInfo, // 启动信息 PPROCESS_INFORMATION ppiProcInfo// 进程信息 ); ``` #### 参数详解 1. **pszApplicationName** 指向可执行文件完整路径的字符串,可为NULL。若为NULL,则从`pszCommandLine`提取可执行文件名[^1]。 2. **pszCommandLine** 命令行参数字符串(需可修改缓冲区),格式需包含可执行文件名: ```cpp TCHAR cmdLine[] = _T("notepad.exe C:\\test.txt"); ``` > 引用[2]特别说明:原型为`PTSTR`,要求传递非常量字符串地址[^2]。 3. **psaProcess/psaThread** 进程/线程安全属性结构指针,通常设为NULL(默认安全描述符)。 4. **bInheritHandles** `TRUE`时子进程继承父进程所有可继承句柄(文件/管道等)。 5. **fdwCreate** 创建标志组合(位掩码): - `CREATE_NEW_CONSOLE`:新建控制台窗口 - `CREATE_SUSPENDED`:创建后挂起主线程 - `DETACHED_PROCESS`:无控制台窗口 - `CREATE_SEPARATE_WOW_VDM`:为16位应用创建独立VDM[^4] 6. **pvEnvironment** 环境变量块指针,NULL表示继承父进程环境。 7. **pszCurDir** 子进程工作目录,NULL表示继承父进程目录。 8. **psiStartInfo** ```cpp STARTUPINFO si = { sizeof(si) }; // 必须初始化cb成员 si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOW; // 窗口显示方式 ``` 9. **ppiProcInfo** ```cpp PROCESS_INFORMATION pi; CreateProcess(..., &pi); // 使用后需关闭句柄 CloseHandle(pi.hProcess); CloseHandle(pi.hThread); ``` #### 执行流程 1. 系统创建进程内核对象(初始化使用计数=2) 2. 创建虚拟地址空间并加载.exe 3. 创建主线程内核对象(使用计数=2) 4. 执行C/C++运行时启动代码 5. 调用入口函数(`WinMain`/`main`)[^2] #### 完整示例 ```cpp #include <windows.h> #include <tchar.h> int main() { STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; TCHAR cmdLine[] = _T("calc.exe"); // 可修改缓冲区 if (CreateProcess( NULL, // 从命令行获取可执行文件 cmdLine, // 命令行参数 NULL, // 默认进程安全属性 NULL, // 默认线程安全属性 FALSE, // 不继承句柄 0, // 无特殊标志 NULL, // 继承环境变量 NULL, // 继承当前目录 &si, // 启动信息 &pi) // 接收进程信息 ) { WaitForSingleObject(pi.hProcess, INFINITE); // 等待进程结束 CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } return 0; } ``` #### 注意事项 1. 进程创建是原子操作,期间禁止其他线程操作[^3] 2. 命令行缓冲区需可修改(非常量字符数组) 3. 必须关闭`PROCESS_INFORMATION`中的句柄 4. 创建控制台程序时使用`CREATE_NEW_CONSOLE`避免冲突
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值