1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #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 \n" , pi.dwProcessId); printf ( " 新进程的主线程ID号:%d \n" , pi.dwThreadId); } return 0; } |
在调用CreatePricess的前两个参数:pszApplicationName和pszCommandLine时可能崩溃的问题: pszApplicationName和pszCommandLine参数分别指定新进程要使用的执行体文件的名称,以及要传给新进程的命令行字符串。先来谈谈pszCommandLine参数。 注意,pszCommandLine参数被原型化为一个PTSTR。这意味着CreateProces期望你传入的是一个非“常量字符串”的地址。在内部,CreateProcess实际上会修改你传给它的命令行字符串。但在CreateProcess返回之前,它会将这个字符串还原为原来的形式。 这是很重要的,因为如果命令行字符串包含在你的文件映像的只读部分,就会引起访问冲突(违例)。例如,以下代码就会导致冲突,因为Microsoft的C/C++编译器把"NOTEPAD"字符串放在只读内存中:
1 2 3 4 | 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之前,把常量字符串复制到一个临时缓冲区,如下所示:
1 2 3 | 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 |
在调用CreatePricess的前两个参数:pszApplicationName和pszCommandLine时可能崩溃的问题:
pszApplicationName和pszCommandLine参数分别指定新进程要使用的执行体文件的名称,以及要传给新进程的命令行字符串。先来谈谈pszCommandLine参数。
注意,pszCommandLine参数被原型化为一个PTSTR。这意味着CreateProces期望你传入的是一个非“常量字符串”的地址。在内部,CreateProcess实际上会修改你传给它的命令行字符串。但在CreateProcess返回之前,它会将这个字符串还原为原来的形式。
这是很重要的,因为如果命令行字符串包含在你的文件映像的只读部分,就会引起访问冲突(违例)。例如,以下代码就会导致冲突,因为Microsoft的C/C++编译器把"NOTEPAD"字符串放在只读内存中:
1 2 3 4 | 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之前,把常量字符串复制到一个临时缓冲区,如下所示:
1 2 3 | 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
关闭 TerminateProcess(pi.hProcess,0);