#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"字符串放在只讀內存中:
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
