我更改了旧的MFC应用程序以支持Unicode。现在代码如下所示。基本上我在这里调用.cmd文件:
STARTUPINFO StartupInfo;
DWORD dwErrorCode;
PROCESS_INFORMATION * processInformation = new PROCESS_INFORMATION[2];
for (int i = 0; i < 2; i++)
{
GetStartupInfo(&StartupInfo);
if (processList[i].bHide)
{
StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow = SW_HIDE;
}
if (processList[i].sCustomTitle.GetLength())
StartupInfo.lpTitle = processList[i].sCustomTitle.GetBuffer(processList[i].sCustomTitle.GetLength());
CreateProcess(NULL,
/*I changed LPSTR to LPWSTR*/(LPWSTR)(LPCTSTR)processList[i].sCommandLine,
NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartupInfo, &processInformation[i]);
[...]
}
我做的唯一更改是将LPSTR
更改为LPWSTR
。在转换为Unicode之前,这没有任何问题。但现在它没有运行。可能是什么原因?在转换为Unicode
支持时,我是否遗漏了任何需要做的事情?
P.S。:我调试并检查了所有参数。他们看起来很好。 sCommandLine
是CString
中的PROCESS_STARTUP_INFO struct
变量。
答案 0 :(得分:1)
如评论中所述,您不应该投射你的字符串。您应该使用临时变量,因为documentation中的以下注释:
此函数的Unicode版本CreateProcessW可以修改此字符串的内容。因此,此参数不能是只读内存的指针(例如const变量或文字字符串)。如果此参数是常量字符串,则该函数可能会导致访问冲突。
最近我遇到了类似的问题。我通过以下方式解决了它(我试图使它成为防弹):
// The maximum length of the command line string is 32,768 characters,
// including the Unicode terminating null character.
#define MAX_CMD_LINE_LEN 32768
// Use a temporary variable for the command line.
TCHAR szCmdLine[MAX_CMD_LINE_LENGTH];
// Get the length of the command line. Crop the command line if it is too long.
int iLen = min(processList[i].sCommandLine.GetLength(), MAX_CMD_LINE_LEN - 1);
// Copy the command line string to the temporary variable.
_tcsncpy_s(szCmdLine, processList[i].sCommandLine, iLen);
// Create the process by passing the temporary variable holding a copy of your
// original command line string.
CreateProcess(NULL,
szCmdLine,
NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL,
NULL, &StartupInfo, &processInformation[i]);
此解决方案应编译并适用于Unicode和非Unicode构建。