function exec_cmd_line(const sCmd: AnsiString; var nExitCode: Cardinal; nDefWaitTime: Cardinal = 10 * 1000): string;

//const
// aExitCode_CreateProcessError = 222;

var
si: TStartupInfoA;
pi: TProcessInformation;

//aCurrDir: string;

//aRet: Cardinal;


begin


FillChar(si, SizeOf(si), #0);
FillChar(pi, SizeOf(pi), #0);

// Windows.GetStartupInfo(si);
si.cb := SizeOf(si);
si.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
si.wShowWindow := SW_HIDE;


//BOOL WINAPI CreateProcess(
// LPCTSTR lpApplicationName,
// LPTSTR lpCommandLine,
// LPSECURITY_ATTRIBUTES lpProcessAttributes,
// LPSECURITY_ATTRIBUTES lpThreadAttributes,
// BOOL bInheritHandles,
// DWORD dwCreationFlags,
// LPVOID lpEnvironment,
// LPCTSTR lpCurrentDirectory,
// LPSTARTUPINFO lpStartupInfo,
// LPPROCESS_INFORMATION lpProcessInformation
//);

if Windows.CreateProcessA(
nil, // LPCTSTR lpApplicationName, // pointer to name of executable module
PAnsiChar(sCmd), //LPTSTR lpCommandLine, // pointer to command line string
nil, //LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes
nil, //LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes
True, //BOOL bInheritHandles, // handle inheritance flag
0, //DWORD dwCreationFlags, // creation flags
nil, //LPVOID lpEnvironment, // pointer to new environment block
nil, //LPCTSTR lpCurrentDirectory, // pointer to current directory name
si, //LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
pi //LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
) then begin

if Windows.WaitForInputIdle(pi.hProcess, INFINITE) <> 0 then begin

end;

if Windows.WaitForSingleObject(pi.hProcess, nDefWaitTime) = Windows.WAIT_TIMEOUT then
Windows.TerminateProcess(pi.hProcess, Windows.WAIT_TIMEOUT);

Windows.GetExitCodeProcess(pi.hProcess, nExitCode);

end
else begin
nExitCode := GetLastError;
end;

//nExitCode := nExitCode mod 256;

end;