• Win32 API编程:使用CreateProcess创建新进程


    #include <windows.h>
    #include <tchar.h>
    #include <stdio.h>
    
    int main(int argc, char* argv[])
    {
    	TCHAR szCommandLine[] = TEXT("NOTEPAD");//或者WCHAR
    	//LPWSTR szCommandLine = TEXT("NOTEPAD");//错误
    	//STARTUPINFO si = { sizeof(si) };
    	STARTUPINFO si;
    	PROCESS_INFORMATION pi;
    	ZeroMemory(&si, sizeof(si));
    	si.cb = sizeof(si);
    	ZeroMemory(&pi, sizeof(pi));
    
    	si.dwFlags = STARTF_USESHOWWINDOW;	// 指定wShowWindow成员有效
    	si.wShowWindow = TRUE;			// 此成员设为TRUE的话则显示新建进程的主窗口,
    						// 为FALSE的话则不显示
    	BOOL bRet = ::CreateProcess (
    		NULL,			// 不在此指定可执行文件的文件名
    		szCommandLine,		// 命令行参数
    		NULL,			// 默认进程安全性
    		NULL,			// 默认线程安全性
    		FALSE,			// 指定当前进程内的句柄不可以被子进程继承
    		CREATE_NEW_CONSOLE,	// 为新进程创建一个新的控制台窗口
    		NULL,			// 使用本进程的环境变量
    		NULL,			// 使用本进程的驱动器和目录
    		&si,
    		&pi);
    
    	if(bRet)
    	{
    		WaitForSingleObject(pi.hProcess, INFINITE);
    		// 既然我们不使用两个句柄,最好是立刻将它们关闭
    		::CloseHandle (pi.hThread);
    		::CloseHandle (pi.hProcess);
    
    		printf(" 新进程的进程ID号:%d 
    ", pi.dwProcessId);
    		printf(" 新进程的主线程ID号:%d 
    ", pi.dwThreadId);	
    	}
    	return 0;
    }
    

    在调用CreatePricess的前两个参数:pszApplicationName和pszCommandLine时可能崩溃的问题:

    pszApplicationName和pszCommandLine参数分别指定新进程要使用的执行体文件的名称,以及要传给新进程的命令行字符串。先来谈谈pszCommandLine参数。
    注意,pszCommandLine参数被原型化为一个PTSTR。这意味着CreateProces期望你传入的是一个非“常量字符串”的地址。在内部,CreateProcess实际上会修改你传给它的命令行字符串。但在CreateProcess返回之前,它会将这个字符串还原为原来的形式。
    这是很重要的,因为如果命令行字符串包含在你的文件映像的只读部分,就会引起访问冲突(违例)。例如,以下代码就会导致冲突,因为Microsoft的C/C++编译器把"NOTEPAD"字符串放在只读内存中:

    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    CreateProcess(NULL, TEXT("NOTEPAD"), NULL, NULL,
    FALSE, 0, NULL, NULL, &si, &pi);
    

    CreateProcess试图修改字符串时,会引起一个访问冲突(Microsoft C/C++编译器的早期版本把字符串放在可读/写内存中。所以对CreateProcess函数的调用不会引起访问冲突)。

    解决这个问题的最佳方式是:在调用CreateProcess之前,把常量字符串复制到一个临时缓冲区,如下所示:

    TCHAR szCommandLine[] = TEXT("NOTEPAD");
    CreateProcess(NULL, szCommandLine, NULL, NULL,
    FALSE, 0, NULL, NULL, &si, &pi); 
    

    涉及的字符关系:

    char* 替换: LPSTR
    const char* 替换: LPCSTR
    WCHAR* 替换: LPWSTR
    const WCHAR* 替换: LPCWSTR (C在W之前, 因为 const 在 WCHAR之前)
    TCHAR* 替换: LPTSTR
    const TCHAR* 替换: LPCTSTR

  • 相关阅读:
    iOS获取设备UUID和IDFA
    iOS之Xcode提交App中断出现:Cannot proceed with delivery: an existing transporter instance is currently uploading this package
    iOS 打测试包给测试人员测试,两种安装方式
    ios APP进程杀死之后和APP在后台接收到推送点击跳转到任意界面处理
    iOS中统计平台的使用
    Android APK反编译
    Linux客户端、服务器、窗口管理器的关系
    Linux中ctrl-c, ctrl-z, ctrl-d 区别
    如何下载百度网盘已失效资源链接
    svn 批量更新 bat脚本
  • 原文地址:https://www.cnblogs.com/fancing/p/6477918.html
Copyright © 2020-2023  润新知