int LaunchSubProcess( const AString & args ) { // try to make a copy of our exe AStackString<> exeName; Env::GetExePath( exeName ); AStackString<> exeNameCopy( exeName ); exeNameCopy += ".copy"; Timer t; while ( FileIO::FileCopy( exeName.Get(), exeNameCopy.Get() ) == false ) { if ( t.GetElapsed() > 5.0f ) { AStackString<> msg; msg.Format( "Failed to make sub-process copy - error: %u (0x%x)\n\nSrc: %s\nDst: %s\n", Env::GetLastErr(), Env::GetLastErr(), exeName.Get(), exeNameCopy.Get() ); ShowMsgBox( msg.Get() ); return -2; } Thread::Sleep( 100 ); } AStackString<> argsCopy( args ); argsCopy += " -subprocess"; // allow subprocess to access the mutex g_OneProcessMutex.Unlock(); Process p; #if defined( __WINDOWS__ ) p.DisableHandleRedirection(); // TODO:MAC TODO:LINUX is this needed? #endif p.Spawn( exeNameCopy.Get(), argsCopy.Get(), nullptr, nullptr ); p.Detach(); return 0; }
bool ChildProcess::Run(bool showCommand, std::wstring args) { UIETWASSERT(!hProcess_); if (showCommand) outputPrintf(L"%s\n", args.c_str()); SECURITY_ATTRIBUTES security = { sizeof(security), 0, TRUE }; hStdOutput_ = CreateFile(kPipeName, GENERIC_WRITE, 0, &security, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE); if (hStdOutput_ == INVALID_HANDLE_VALUE) return false; if (!DuplicateHandle(GetCurrentProcess(), hStdOutput_, GetCurrentProcess(), &hStdError_, 0, TRUE, DUPLICATE_SAME_ACCESS)) return false; STARTUPINFO startupInfo = {}; startupInfo.hStdOutput = hStdOutput_; startupInfo.hStdError = hStdError_; startupInfo.hStdInput = INVALID_HANDLE_VALUE; startupInfo.dwFlags = STARTF_USESTDHANDLES; PROCESS_INFORMATION processInfo = {}; DWORD flags = CREATE_NO_WINDOW; // Wacky CreateProcess rules say args has to be writable! std::vector<wchar_t> argsCopy(args.size() + 1); wcscpy_s(&argsCopy[0], argsCopy.size(), args.c_str()); BOOL success = CreateProcess(exePath_.c_str(), &argsCopy[0], NULL, NULL, TRUE, flags, NULL, NULL, &startupInfo, &processInfo); if (success) { CloseHandle(processInfo.hThread); hProcess_ = processInfo.hProcess; return true; } else { outputPrintf(L"Error %d starting %s, %s\n", (int)GetLastError(), exePath_.c_str(), args.c_str()); } return false; }