| 408 | } |
| 409 | |
| 410 | int32 SDLPlatform::CreateProcess(CreateProcessSettings& settings) |
| 411 | { |
| 412 | LOG(Info, "Command: {0} {1}", settings.FileName, settings.Arguments); |
| 413 | if (settings.WorkingDirectory.HasChars()) |
| 414 | LOG(Info, "Working directory: {0}", settings.WorkingDirectory); |
| 415 | |
| 416 | int32 result = 0; |
| 417 | const bool captureStdOut = settings.LogOutput || settings.SaveOutput; |
| 418 | const StringAnsi cmdLine = StringAnsi::Format("\"{0}\" {1}", StringAnsi(settings.FileName), StringAnsi(settings.Arguments)); |
| 419 | StringAnsi workingDirectory(settings.WorkingDirectory); |
| 420 | |
| 421 | // Populate environment with current values from parent environment. |
| 422 | // SDL does not populate the environment with the latest values but with a snapshot captured during initialization. |
| 423 | Dictionary<String, String> envDictionary; |
| 424 | GetEnvironmentVariables(envDictionary); |
| 425 | SDL_Environment* env = SDL_CreateEnvironment(false); |
| 426 | for (auto iter = envDictionary.Begin(); iter != envDictionary.End(); ++iter) |
| 427 | SDL_SetEnvironmentVariable(env, StringAnsi(iter->Key).Get(), StringAnsi(iter->Value).Get(), true); |
| 428 | for (auto iter = settings.Environment.Begin(); iter != settings.Environment.End(); ++iter) |
| 429 | SDL_SetEnvironmentVariable(env, StringAnsi(iter->Key).Get(), StringAnsi(iter->Value).Get(), true); |
| 430 | |
| 431 | // Parse argument list with possible quotes included |
| 432 | Array<StringAnsi> arguments; |
| 433 | arguments.Add(StringAnsi(settings.FileName)); |
| 434 | if (CommandLine::ParseArguments(settings.Arguments, arguments)) |
| 435 | { |
| 436 | LOG(Error, "Failed to parse arguments for process {}: '{}'", settings.FileName.Get(), settings.Arguments.Get()); |
| 437 | return -1; |
| 438 | } |
| 439 | Array<const char*> cmd; |
| 440 | for (const StringAnsi& str : arguments) |
| 441 | cmd.Add(str.Get()); |
| 442 | cmd.Add((const char*)0); |
| 443 | |
| 444 | #if PLATFORM_WINDOWS |
| 445 | bool background = !settings.WaitForEnd || settings.HiddenWindow; // This also hides the window on Windows |
| 446 | #else |
| 447 | bool background = !settings.WaitForEnd; |
| 448 | #endif |
| 449 | |
| 450 | SDL_PropertiesID props = SDL_CreateProperties(); |
| 451 | SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, cmd.Get()); |
| 452 | SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, env); |
| 453 | SDL_SetBooleanProperty(props, SDL_PROP_PROCESS_CREATE_BACKGROUND_BOOLEAN, background); |
| 454 | #if !PLATFORM_WEB |
| 455 | if (workingDirectory.HasChars()) |
| 456 | SDL_SetStringProperty(props, SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING, workingDirectory.Get()); |
| 457 | #endif |
| 458 | if (captureStdOut) |
| 459 | { |
| 460 | SDL_SetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_APP); |
| 461 | SDL_SetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDERR_NUMBER, SDL_PROCESS_STDIO_APP); |
| 462 | } |
| 463 | SDL_Process* process = SDL_CreateProcessWithProperties(props); |
| 464 | SDL_DestroyProperties(props); |
| 465 | SDL_DestroyEnvironment(env); |
| 466 | if (process == nullptr) |
| 467 | { |
no test coverage detected