创建新的进程是Windows
程序开发的重要部分,它可以用于实现许多功能,例如进程间通信、并行处理等。其中,常用的三种创建进程的方式分别是WinExec()
、ShellExecute()
和CreateProcessA()
,这三种创建进程的方式各有特点。如果需要创建简单进程或从其他程序启动新进程,可以使用WinExec()
或ShellExecute()
函数。如果需要对新进程进行更精细的配置,例如控制进程参数、指定安全级别、传递特定的命令和参数等,可以使用CreateProcessA()
函数。
首先介绍WinExec
函数,该函数是创建进程的一种方式,它使用较为简单,但缺乏对进程参数和安全性等方面的控制。使用WinExec()
函数,可以传递一个字符串类型的参数,该参数中指定了要启动的进程名和参数等信息。但是,由于WinExec()
函数没有提供区分进程启动成功和失败的返回值,且无法从函数返回的进程句柄获得与进程相关的信息,因此使用较为有限。
该函数的原型为:
UINT WinExec(
LPCSTR lpCmdLine,
UINT uCmdShow
);
其参数说明如下:
WinExec 函数的返回值是一个无符号整数,它表示进程是否成功启动。若成功启动,则返回值为任务句柄。否则,返回值为0。但是该函数也存在一些问题,例如ANSI编码、不支持进程标识符等,建议在实际开发中使用更为灵活的CreateProcess()
或ShellExecute()
函数。
#include
#include
BOOL WinExec(char *pszExePath, UINT uiCmdShow)
{
UINT uiRet = 0;
uiRet = WinExec(pszExePath, uiCmdShow);
if (31 < uiRet)
{
return TRUE;
}
return FALSE;
}
int main(int argc, char * argv[])
{
int ret = 0;
ret = WinExec("c:\\windows\\system32\\notepad.exe",TRUE);
printf("执行状态: %d \n", ret);
system("pause");
return 0;
}
创建进程的第二个函数是ShellExecute
,该函数提供了很多功能,例如可以启动进程、打开文件、运行脚本等等。ShellExecute()
函数的优点是可以控制进程的启动方式、传递命令参数,并对返回值进行判断,通过传递参数来控制启动进程的方式,比如最大化或最小化窗口,或者在后台启动进程。
该函函数原型如下:
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
参数说明:
该函数返回HINSTANCE
类型的值,如果没有执行或则执行失败,它将返回一个值为ERROR_FILE_NOT_FOUND
或ERROR_BAD_FORMAT
的值。
#include
#include
BOOL MyShellExecute(char *pszExePath, UINT uiCmdShow)
{
HINSTANCE hInstance = 0;
hInstance = ShellExecute(NULL, NULL, pszExePath, NULL, NULL, uiCmdShow);
if (32 < (DWORD)hInstance)
{
return TRUE;
}
return FALSE;
}
int main(int argc, char * argv[])
{
int ret = 0;
ret = MyShellExecute("c:\\windows\\system32\\notepad.exe", TRUE);
printf("执行状态: %d \n", ret);
system("pause");
return 0;
}
最后一个创建进程的函数是CreateProcess()
该函数提供了比较灵活的进程控制,相比于其他API
函数,例如WinExec()
和ShellExecute()
,它可以更详细地控制进程的执行,如进程窗口的大小和位置,输出、输入和错误信息的控制等,并且能够获取到新进程的标识符以及进程句柄。同时CreateProcess()
也具有更高的系统安全性。因此,在实际开发中,开发人员往往使用 CreateProcess()
函数进行进程控制、管理和处理。
其函数原型如下:
BOOL CreateProcess(
LPCSTR lpApplicationName, // 可执行文件名或命令行调用
LPSTR lpCommandLine, // 字符串形式的命令行参数
LPSECURITY_ATTRIBUTES lpProcessAttributes,// 进程的安全属性
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性
BOOL bInheritHandles, // 建立进程时是否继承父句柄
DWORD dwCreationFlags, // 进程标记
LPVOID lpEnvironment, // 进程环境空间块的指针
LPCSTR lpCurrentDirectory, // 当前工作目录的指针
LPSTARTUPINFOA lpStartupInfo, // 指向 StartupInfo 结构的指针
LPPROCESS_INFORMATION lpProcessInformation // 指向 ProcessInformation 结构的指针
);
参数说明:
如果仅仅只是需要将一个进程拉起来,那么只需要传递三个参数即可,其余参数可以全部使用0进行填充,如下所示;
#include
#include
BOOL ExecRun(LPCSTR exe_file)
{
PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
si.cb = sizeof(STARTUPINFO);
BOOL bRet = CreateProcessA(exe_file, 0, 0, 0, 0, 0, 0, 0, &si, &pi);
if (bRet != FALSE)
CloseHandle(pi.hProcess);
return TRUE;
return FALSE;
}
int main(int argc, char * argv[])
{
int ret = 0;
ret = ExecRun("c:\\windows\\system32\\notepad.exe");
printf("执行状态: %d \n", ret);
system("pause");
return 0;
}