有一个如何在堆栈交换here上调用CreateProcess的示例,但是在Windows 10上似乎不再支持它,并且您必须使用unicode版本CreateProcessW。
与ASCI版本类似,我正在寻找一个例子:
答案 0 :(得分:3)
在这方面,Windows 10并没有什么新鲜事。您的问题实际上是关于Unicode与ANSI以及Visual Studio的使用Unicode的新默认设置。
CreateProcess
是一个宏,它被定义为
#ifdef UNICODE
#define CreateProcess CreateProcessW
#else
#define CreateProcess CreateProcessA
#endif // !UNICODE
此外,STARTUPINFO
是STARTUPINFOA
和STARTUPINFOW
CreateProcessA
使用ANSI字符串char*
和STARTUPINFOA
CreateProcessW
使用Unicode宽字符串wchar_t*
和STARTUPINFOW
如果您坚持使用ANSI(不推荐),请转到项目设置 - >字符集并禁用Unicode。
如果您坚持使用带有Unicode设置的ANSI版本(仍然不推荐),则需要
//Using ANSI when UNICODE is defined (not recommended):
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
std::string path = "c:\\windows\\notepad.exe \"c:\\test\\_text.txt\"";
//if not using C++11 or later, force a zero at the end
//to make sure path is null-ternminated
path.push_back(0);
if(CreateProcessA(NULL, &path[0], NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
只要目录名与ANSI兼容,上述代码就可以正常工作。但推荐的版本是:
//recommended:
{
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
std::wstring path = L"c:\\windows\\notepad.exe \"c:\\test\\_text.txt\"";
//if not using C++11 or later, force a zero at the end
//to make sure path is null-ternminated
path.push_back(0);
if(CreateProcess(0, &path[0], NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
另外,不要将常量字符串转换为字符串,如下所示:
wchar_t* arg_concat = const_cast<wchar_t*>( input.c_str() );
CreateProcess
中的第二个参数应为wchar_t*
,因为该过程可能会修改命令行。
答案 1 :(得分:1)
这个例子被评论并希望自我解释。
#ifdef _WIN32
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <cstdlib>
#include <string>
#include <algorithm>
class process
{
public:
static PROCESS_INFORMATION launchProcess(std::string app, std::string arg)
{
// Prepare handles.
STARTUPINFO si;
PROCESS_INFORMATION pi; // The function returns this
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
//Prepare CreateProcess args
std::wstring app_w(app.length(), L' '); // Make room for characters
std::copy(app.begin(), app.end(), app_w.begin()); // Copy string to wstring.
std::wstring arg_w(arg.length(), L' '); // Make room for characters
std::copy(arg.begin(), arg.end(), arg_w.begin()); // Copy string to wstring.
std::wstring input = app_w + L" " + arg_w;
wchar_t* arg_concat = const_cast<wchar_t*>( input.c_str() );
const wchar_t* app_const = app_w.c_str();
// Start the child process.
if( !CreateProcessW(
app_const, // app path
arg_concat, // Command line (needs to include app path as first argument. args seperated by whitepace)
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
)
{
printf( "CreateProcess failed (%d).\n", GetLastError() );
throw std::exception("Could not create child process");
}
else
{
// Return process handle
return pi;
}
}
static bool checkIfProcessIsActive(PROCESS_INFORMATION pi)
{
// Check if handle is closed
if ( pi.hProcess == NULL )
{
printf( "Process handle is closed or invalid (%d).\n");
return FALSE;
}
// If handle open, check if process is active
DWORD lpExitCode = 0;
if( GetExitCodeProcess(pi.hProcess, &lpExitCode) == 0)
{
printf( "Cannot return exit code (%d).\n", GetLastError() );
throw std::exception("Cannot return exit code");
}
else
{
if (lpExitCode == STILL_ACTIVE)
{
return TRUE;
}
else
{
return FALSE;
}
}
}
static bool stopProcess( PROCESS_INFORMATION &pi)
{
// Check if handle is invalid or has allready been closed
if ( pi.hProcess == NULL )
{
printf( "Process handle invalid. Possibly allready been closed (%d).\n");
return 0;
}
// Terminate Process
if( !TerminateProcess(pi.hProcess,1))
{
printf( "ExitProcess failed (%d).\n", GetLastError() );
return 0;
}
// Wait until child process exits.
if( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_FAILED)
{
printf( "Wait for exit process failed(%d).\n", GetLastError() );
return 0;
}
// Close process and thread handles.
if( !CloseHandle( pi.hProcess ))
{
printf( "Cannot close process handle(%d).\n", GetLastError() );
return 0;
}
else
{
pi.hProcess = NULL;
}
if( !CloseHandle( pi.hThread ))
{
printf( "Cannot close thread handle (%d).\n", GetLastError() );
return 0;
}
else
{
pi.hProcess = NULL;
}
return 1;
}
};//class process
#endif //win32