您需要擺脫傳遞的前2個參數值附近的額外括號。
但是,更重要的是,您需要擺脫LPTSTR
類型。如果你的項目配置爲編譯對於Unicode,CreateProcess()
將映射到CreateProcessW()
,並LPTSTR
將映射到wchar_t*
,這樣你就會型鑄造窄const char[]
文字的wchar_t*
指針,並最終通過垃圾CreateProcessW()
,這很容易解釋因爲你看到的錯誤。創建TCHAR[]
字符串字面正確的方法是使用,而不是一個類型轉換的TEXT()
宏(見Working with Strings MSDN上有詳細介紹):
hr = CreateProcess(NULL, TEXT("C:\\Windows\\System32\\notepad.exe"), NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);
然而,要注意CreateProcess()
documentation:
lpCommandLine [輸入,輸出,可選]
要執行的命令行。該字符串的最大長度爲32,768個字符,其中包括Unicode終止空字符。如果lpApplicationName
爲NULL,則lpCommandLine的模塊名稱部分限制爲MAX_PATH
個字符。
此函數的Unicode版本CreateProcessW
可以修改此字符串的內容。因此,該參數不能是指向只讀內存的指針(例如const變量或文字字符串)。如果此參數是一個常量字符串,則該函數可能會導致訪問衝突。
您可以執行以下操作來避免:
TCHAR szCmdLine[] = TEXT("C:\\Windows\\System32\\notepad.exe");
hr = CreateProcess(NULL, szCmdLine, NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);
或者:
WCHAR szCmdLine[] = L"C:\\Windows\\System32\\notepad.exe";
hr = CreateProcessW(NULL, szCmdLine, NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);
否則,直接使用的CreateProcess()
ANSI版本,可以放心地傳遞一個字符串字面到:
hr = CreateProcessA(NULL, "C:\\Windows\\System32\\notepad.exe", NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);
在旁註中,您不需要指定notepad.exe
的完整路徑,因爲Windows知道它位於何處。您可以單獨使用"notepad.exe"
。
但是,如果您確實指定了完整路徑,則必須考慮應用程序的位數。如果您的應用程序編譯爲32位,並且在64位系統上運行,則C:\Windows\System32\notepad.exe
將重定向到C:\Windows\SysWOW64\notepad.exe
,這是32位版本的記事本。如果你想運行記事本的64位版本,你將不得不使用C:\Windows\Sysnative\notepad.exe
代替,每WOW64文檔:
File System Redirector
的%windir%\System32
目錄保留爲64位應用程序。當創建64位版本的DLL時,大多數DLL文件名不會更改,因此32位版本的DLL存儲在不同的目錄中。 WOW64通過使用文件系統重定向器來隱藏這種差異。
在大多數情況下,每當一個32位的應用程序試圖訪問%windir%\System32
,訪問被重定向到%windir%\SysWOW64
。訪問%windir%\lastgood\system32
被重定向到%windir%\lastgood\SysWOW64
。訪問%windir%\regedit.exe
被重定向到%windir%\SysWOW64\regedit.exe
。
...
32位應用程序可以通過爲%windir%\System32
代%windir%\Sysnative
訪問本地系統目錄。 WOW64將Sysnative
識別爲用於指示文件系統不應該重定向訪問的特殊別名。該機制靈活且易於使用,因此,它是推薦的繞過文件系統重定向的機制。請注意,64位應用程序不能使用Sysnative
別名,因爲它不是真正的虛擬目錄。
Sysnative
只適用於運行在WOW64仿真器內的32位應用程序。您可以在32位應用程序運行在32位系統上使用System32
,和64位系統上運行64位應用程序:
TCHAR szCmdLine[MAX_PATH];
#ifndef _WIN64
BOOL bIsWow64Process = FALSE;
if (IsWow64Process(GetCurrentProcess(), &bIsWow64Process) && bIsWow64Process)
lstrcpy(szCmdLine, TEXT("C:\\Windows\\Sysnative\\notepad.exe"));
else
#endif
lstrcpy(szCmdLine, TEXT("C:\\Windows\\System32\\notepad.exe"));
hr = CreateProcess(NULL, szCmdLine, NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);
但是,你應該考慮到,並不是每個人都安裝帳戶Windows在C:\Windows
文件夾中,因此您應該詢問Windows系統文件夾實際所在的位置:
TCHAR szSysDir[MAX_PATH];
#ifndef _WIN64
BOOL bIsWow64Process = FALSE;
if (IsWow64Process(GetCurrentProcess(), &bIsWow64Process) && bIsWow64Process)
{
TCHAR szWinDir[MAX_PATH];
GetWindowsDirectory(szWinDir, MAX_PATH);
PathCombine(szSysDir, szWinDir, TEXT("Sysnative");
}
else
#endif
GetSystemDirectory(szSysDir, MAX_PATH);
TCHAR szCmdLine[MAX_PATH];
PathCombine(szCmdLine, szSysDir, TEXT("notepad.exe");
hr = CreateProcess(NULL, szCmdLine, NULL,
NULL, NULL, FALSE, 0, NULL,
NULL, &StartupInfo, &ProcessInfo);
嘗試交換前兩個參數。第二個參數不能是一個文字字符串,但第一個可以。 – SBS
對CreateProcess()的第一個參數使用逗號運算符似乎很奇怪。你有'(NULL,(LPTSTR)「C:\\ Windows \\ System32 \\ notepad.exe」)'作爲第一個參數,它計算NULL並拋出它,然後評估字符串的強制轉換。在['CreateProcess()'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v = vs.85).aspx)上檢查MSDN - 你不指定一個命令(但我不知道這是否重要)。 –
@JonathanLeffler你說得對 - 我沒有意識到附加的括號。我確信它不是這種意圖。 – SBS