WaitForSingleObject
Instead of waiting for a process to end by polling its exit code with GetExitCodeProcess, which might hang as explained above, use e.g. WaitForSingleObject, or a family member.
WaitForSingleObject(pi.hProcess, INFINITE)
val exitCode: DWORDVar = alloc()
val result = GetExitCodeProcess(pi.hProcess, exitCode.ptr).convert<Int>()
CloseHandle(pi.hProcess)
CloseHandle(pi.hThread)
return if (result == 0) { // If result is 0, GetExitCodeProcess failed
-1
} else {
exitCode.value.convert()
}